fullCalendarjs 方法 fullCalendar('clientEvents') returns 重复事件

fullCalendarjs method fullCalendar('clientEvents') returns duplicate events

我正在使用 fullcalendar.io

我通过 evenSources 添加事件来动态填充我的日历。如:

$('.add-more-events').on('click', function(){
    var myEventSourceUrl = // ... get the event source url somehow
    var eventSourceColor = // ... get the color for this source
    var eventSource = {
        type: 'GET',
        url: myEventSourceUrl,
        color: eventSourceColor
    };
    $('.my-calendar').fullCalendar('addEventSource', eventSource);
}

同样,我通过 eventSource 删除 事件动态地取消填充我的日历。如:

$('.remove-some-events').on('click', function(){
    var myEventSourceUrl = // ... get the event source url somehow
    var eventSourceColor = // ... get the color for this source
    var eventSource = {
        type: 'GET',
        url: myEventSourceUrl,
        color: eventSourceColor
    };
    $('.my-calendar').fullCalendar('removeEventSource', eventSource);
}

到目前为止一切顺利:从视觉上看,事件按预期出现在日历中(已填充),并在日历中消失(未填充)。也就是说,每当我点击相关按钮时。


在某些时候,我想重新初始化我的日历并重新显示我日历中最后出现的事件(保留我想的最后一个 eventSources)。

伪代码如下所示:

1. Back up my events
2. Destroy my calendar
3. Create & initialize new calendar
4. Add the backed up events (see step 1) to the new calendar

所以我实现了上面的如:

var clientEvents = $('.my-calendar').fullCalendar('clientEvents'); /* [1] */
$('.my-calendar').fullCalendar('destroy'); /* [2] */
$('.my-calendar').fullCalendar(calendarOptions); /* [3] */
var arrayLengthClientEvents = clientEvents.length;
for (var i = 0; i < arrayLengthClientEvents; i++) {
    $('.my-calendar').fullCalendar( 'addEventSource', clientEvents[i].source);  /* [4] */
}

但由于某些原因,我在调用 $('.my-calendar').fullCalendar('clientEvents') 时收到重复的事件。

注意:似乎是在切换周时发生的,虽然不确定,但可能无关。


资源:

clientEvents

Retrieves events that FullCalendar has in memory.
.fullCalendar( 'clientEvents' [, idOrFilter ] ) -> Array

所以它 returns 一系列事件。

您存储它,重新创建 FC,然后 添加每个事件的源。但是源是 URL,许多事件都相同,所以你会得到重复项。

基本上你在做

$('.my-calendar').fullCalendar('addEventSource', {url:"/myfeed"});
$('.my-calendar').fullCalendar('addEventSource', {url:"/myfeed"});

这会给你重复的。

所以要修复它,您可以检查重复项而不是添加它们。添加以下方法:

var filterOutDuplicateEventSources = function(allEventSources){
    var hash = {};
    var remainingEventSources = [];
    var arrayLength = allEventSources.length;
    for (var i = 0; arrayLength !== 0 && i < arrayLength; i++) {
        var currentEventSource = allEventSources[i];
        var currentEventSourceUrl = currentEventSource.url;
        if(currentEventSourceUrl){
            if(hash[currentEventSourceUrl] === 1){
                continue; //skip this event source, we've already added it
            }else{
                hash[currentEventSourceUrl] = 1; // remember that we add this currentEventSourceUrl
                remainingEventSources.push(currentEventSource);
            }
        }else{
            //handle non-url event sources
        }
    }
    return remainingEventSources;
}

使用此方法如:

// Get all event sources
var allEventSources = [];
var arrayLengthClientEvents = clientEvents.length;
for (var i = 0; i < arrayLengthClientEvents; i++) {
    allEventSources.push( clientEvents[i].source );
}

// Filter out duplicated event sources
var remainingEventSources = filterOutDuplicateEventSources( allEventSources );

或者

从技术上讲,我不认为 clientEvents 应该以这种方式使用。您真正需要的是 eventSources 方法。但它不存在(可能是个好东西feature request)。

我可能会尝试将日历的事件源状态存储在 fullcalendar 之外。你说你有开关的按钮,这些基本上是切换吗?是否可以通过简单地查询您的各种控件来确定状态?沿着这些思路的东西可能是更好的解决方案。也许。