Al usar jquery fullCalendar, ¿por qué veo eventos duplicados después de cambiar de mes?

Estoy usando el complemento jquery fullCalendar y tengo un problema extraño.

Cuando cargo el primer mes (diciembre de 2013 en este caso) funciona bien. Llamo a mi evento ajax y devuelvo un conjunto de eventos. Devuelvo 40 eventos de mi servidor y veo 40 eventos renderizados.

Luego me mudo al mes siguiente (enero de 2014) y también funciona bien. (41 eventos del servidor y 41 eventos aparecen en la GUI)

Luego hago clic en ATRÁS para volver a diciembre de 2013 y obtengo el evento ajax, que devuelve los mismos 40 eventos (como arriba), pero cuando el calendario se carga, veo todos los eventos en diciembre duplicados (se muestran 80 eventos en la GUI) aunque Solo devuelvo 40 desde el servidor y veo 40 durante la callback de eventos.

Aquí está mi código:

$('#calendar').fullCalendar({ header: { left: 'prev,next title today', right: '' }, lazyFetching: false, editable: false, timeFormat: 'H:mm{-H:mm} ', viewDisplay: function (view) { ViewDisplay(); }, events: function (start, end, callback) { $('#Month').val($('#calendar').fullCalendar('getDate').getMonth() + 1); $("#Year").val($('#calendar').fullCalendar('getDate').getUTCFullYear()); var serializedFormInfo = $('#rotaForm').serialize(); $.ajax({ url: '/SupportRota/GetEvents/', dataType: 'json', cache: false, data: serializedFormInfo, success: function (data) { callback(data.RotaEvents); } }); } }); 

Intenté agregar lazyLoading: falso, ya que asumí que era una especie de almacenamiento en caché, pero eso no parece resolver el problema.

Puse un punto de quiebre en firebug en la línea

 callback(data.RotaEvents) 

Y veo 40 eventos, pero 80 eventos aparecen en la pantalla durante el escenario mencionado anteriormente.

¿Cualquier sugerencia?

Tal vez una respuesta “incondicional”, pero simple: creo que los eventos pueden almacenarse en caché en el navegador y explicar por qué tiene duplicados.

Solo agrega esta línea antes de tu llamada ajax :

 $('.fc-event').remove(); 

No tiene que preocuparse por si este evento ya se procesó o no, y eso puede ser más rápido en términos de carga.

Si el evento fue configurado con

 $('#calendar').fullCalendar('renderEvent', copiedEventObject, true); 

(como en el ejemplo que encontré) es posible que desee especificar la creación del evento con:

 $('#calendar').fullCalendar('renderEvent', copiedEventObject, false); 

el falso hace que el evento sea “no pegajoso” (que es el comportamiento predeterminado; también puedes soltar el verdadero) y permitirá que el evento desaparezca cuando el calendario vuelva a mostrar los eventos; eso fue para mí 🙂

Debe filtrar los eventos que devuelve de su fuente en función de los argumentos de inicio / fin en combinación con LazyLoading:

Cuando se establece en verdadero (el valor predeterminado), el calendario solo buscará eventos cuando sea absolutamente necesario, minimizando las llamadas AJAX. Por ejemplo, digamos que su calendario comienza en la vista mensual, en febrero. FullCalendar buscará eventos para todo el mes de febrero y los almacenará en su caché interno. Luego, diga que el usuario cambia a la vista semanal y comienza a navegar las semanas en febrero. El calendario evitará la obtención de eventos porque ya tiene esta información almacenada.

Si devuelve todos los eventos, independientemente del período de tiempo, obtendrá duplicados para cada nuevo período de tiempo que cargue. (Por cada nuevo mes que muestres).

En otras palabras: si tiene 10 eventos en diciembre, asegúrese de devolver solo estos 10 eventos cuando el período de tiempo sea diciembre. Debe pasar los parámetros de inicio / finalización a su feed json para reducir los datos enviados al navegador y aprovechar al máximo la función LazyLoading.

Supongo que podrías evitar recargar eventos duplicados:

 events: function (start, end, callback) { $('#Month').val($('#calendar').fullCalendar('getDate').getMonth() + 1); $("#Year").val($('#calendar').fullCalendar('getDate').getUTCFullYear()); if (this.eventsDone && this.eventsDone[start + end]) { return; } var serializedFormInfo = $('#rotaForm').serialize(); $.ajax({ url: '/SupportRota/GetEvents/', dataType: 'json', cache: false, context: this, data: serializedFormInfo, success: function (data) { if (!this.eventsDone) { this.eventsDone = {}; } this.eventsDone[start + end] = true; callback(data.RotaEvents); } }); }