全日历重新获取事件源

Fullcalendar refetch eventsource

正如标题所说,我对完整日历中的 EventSource 有疑问。

目前我可以在完整日历中加载 1 个 google 日历。并且知道如何添加多个 google 日历。

但是,我想使用复选框(链接到它们自己的 google 日历),我用 googleCalendarIds 动态创建了一个数组,这一切都有效,但我无法获得日历到 "refetch" 数组中 google 个日历中的所有事件。

目前,这是我用来填充日历的代码:

document.addEventListener('DOMContentLoaded', function() {
var selected = [];
$('.badgebox:checked').each(function() {
    selected.push({
        'googleCalendarId' : $(this).val(),
        'className' : $(this).data('color')
    });
});
$('.badgebox').on('click', function() {
    if($(this).prop('checked')) {
        selected.push({
            'googleCalendarId' : $(this).val(),
            'className' : $(this).data('color')
        });
        $('#calendar').fullCalendar('refetchResources');
    }else{
        index = selected.findIndex(obj => obj.googleCalendarId === $(this).val());
        selected.splice(index, 1);
        $('#calendar').fullCalendar('refetchResources');
    }
});
var calendarEl = document.getElementById('calendar');
calendar = new FullCalendar.Calendar(calendarEl, {
    header: {
        center: 'dayGridMonth,timeGridWeek'
    },
    views: {
        dayGridMonth: {
            titleFormat: { year: 'numeric', month: '2-digit', day: '2-digit' }
        }
    },
    plugins: [ 'dayGrid', 'timeGrid', 'bootstrap', 'googleCalendar' ],
    googleCalendarApiKey: 'api key',
    eventSources: selected,
    eventClick: function(info) {
        info.jsEvent.preventDefault();
    },
    defaultView: 'timeGridWeek',
    weekNumbers: true,
    locale: 'nl',
    themeSystem: 'bootstrap',
    nowIndicator: true
});

calendar.render();

});

但我得到的是一个错误:

TypeError: $(...).fullCalendar is not a function

我已经加载了所有需要的文件(并且可以看到它们已加载)。

编辑当前代码

这是我现在使用的代码,但仍然不确定如何修复资源部分(刷新):

document.addEventListener('DOMContentLoaded', function() {
    var curSource = [];
    $('.badgebox:checked').each(function() {
        curSource.push({
            'googleCalendarId' : $(this).val(),
            'className' : $(this).data('color')
        });
    });
    var newSource = [];
    var calendarEl = document.getElementById('calendar');
    var calendar = new FullCalendar.Calendar(calendarEl, {
        schedulerLicenseKey: 'key',
        header: {
            center: 'dayGridMonth,timeGridWeek'
        },
        views: {
            dayGridMonth: {
                titleFormat: { year: 'numeric', month: '2-digit', day: '2-digit' }
            }
        },
        plugins: [ 'dayGrid', 'timeGrid', 'bootstrap', 'googleCalendar', 'resourceTimeGrid', 'resourceDayGrid' ],
        googleCalendarApiKey: 'apikey',
        eventSources: curSource,
        eventClick: function(info) {
            info.jsEvent.preventDefault();
        },
        defaultView: 'timeGridWeek',
        weekNumbers: true,
        locale: 'nl',
        themeSystem: 'bootstrap',
        nowIndicator: true
    });
    $('.badgebox').on('change', function() {
        if($(this).prop('checked')) {
            newSource.push({
                'googleCalendarId' : $(this).val(),
                'className' : $(this).data('color')
            });
        }else{
            index = newSource.findIndex(obj => obj.googleCalendarId === $(this).val());
            newSource.splice(index, 1);
        }
        curSource = newSource;
        calendar.getEventSources().forEach(eventSource => {
            eventSource.remove()
        });
        calendar.addEventSource(curSource);
    });
    calendar.render();
});

有什么想法吗?

您添加和删除事件源的逻辑有缺陷 - 它会删除所有以前的源,但只添加当前选定的源(好吧,除了您从未清除 newSource 所以它会一段时间后包含各种重复)。另一个问题是,当您编写 calendar.addEventSource(curSource); 时,您正在添加一个 array 事件源(即使它只包含一个项目)但是添加它就好像它是一个单个事件源 对象。因此它不是 fullCalendar 期望的格式,所以它不会添加任何内容。

相反,您可以只使用与第一次声明日历时相同的逻辑,循环遍历所有当前选中的复选框并将它们全部设置为当前源。这是最简单的方法。只需将该逻辑移动到一个函数中,以便您可以重新使用它。它还消除了包含源列表的全局对象的必要性。像这样:

  function getEventSources() {
    var sources = [];
    $(".badgebox:checked").each(function() {
      sources.push({
        id: $(this).val(),
        'googleCalendarId' : $(this).val(),
        className: $(this).data("color")
      });
    });
    return sources;
  }

然后在日历配置中,通过调用函数设置初始事件源:

eventSources: getEventSources(),

并像这样处理复选框上的 "change" 事件:

  $(".badgebox").on("change", function() {
    //remove event sources
    calendar.getEventSources().forEach(eventSource => {
      eventSource.remove();
    });
    //get currently selected sources
    var sources = getEventSources();

    //add each new source to the calendar
    sources.forEach(eventSource => {
      calendar.addEventSource(eventSource);
    });
  });

我在这里做了一个现场演示:https://codepen.io/ADyson82/pen/Jjoovym。显然,我无法在演示中使用 google 日历,所以我使用硬编码的事件列表完成了它,但整个过程的逻辑是相同的。