FullCalendar在Ajax调用中无法获取实例及刷新问题求助
问题描述
我在Web应用中使用FullCalendar,通过指定代码初始化日历,初始可正常加载JSON文件中的事件。但后台向该JSON文件添加新事件后,无法实现日历刷新。我尝试在Ajax请求的complete回调中调用$('#calendar').fullCalendar('refetchEvents'),但无法获取日历实例,#calendar选择器无返回结果。请问无法获取日历实例的原因是什么?当前实现方式是否正确?
初始化代码
document.addEventListener('DOMContentLoaded', function () { var calendarEl = document.getElementById('rcalendar'); var calendar = new FullCalendar.Calendar(calendarEl, { headerToolbar: { start: 'dayGridMonth,timeGridWeek,timeGridDay saveEvents', center: 'title', end: 'prevYear,prev,next,nextYear' }, customButtons: { newEvent: { text: 'add new reminder', click: function () { alert('clicked custom button 1!'); } }, saveEvents: { text: 'save reminders', click: function () { getDates(); } } }, initialView: 'dayGridMonth', editable: true, slotDuration: '00:30:00', selectable: true, //can click to set event eventTimeFormat: { // like '14:30:00' hour: '2-digit', minute: '2-digit', meridiem: 'short' }, eventSources: [ { url: '/Content/JSON/OpsReminders.json', color: 'blue', textColor: 'white', editable: 'true' } ] }); calendar.render(); });
尝试的Ajax代码
$.ajax({ type: "GET", url: "/OpsAdmin/SaveReminders/", data: {"groupId": '@Model.OpsAdminGroup', "adminId": '@Model.OpAdministrator', "targets": objectStr, "date": eventDate, "time": eventTime, "datetime": eventDateTime, "repeat": rpt, "mon": mon, "tue": tue, "wed": wed, "thu": thu, "fri": fri, "sat": sat, "sun": sun, "msg": msg }, success: function (result) { if (result.saved) { hideModal(); } }, complete: function() { $('#calendar').fullCalendar('refetchEvents'); }, error: function (errorData) { onError(errorData); } });
原因分析
- 选择器ID不匹配:初始化代码中获取的日历元素ID是
rcalendar,但Ajax回调里用的是#calendar,ID不一致导致选择器找不到元素。 - FullCalendar版本API不兼容:你用的是FullCalendar v5及以上版本(通过
new FullCalendar.Calendar()实例化),但fullCalendar('refetchEvents')是v3及更早版本的jQuery式API,v5+已经改用直接调用实例方法的模式。 - 实例作用域受限:初始化时的
calendar变量是DOMContentLoaded回调内部的局部变量,Ajax回调无法访问到这个实例。
正确实现方式
1. 修正作用域,让实例全局可访问
把calendar变量提升到全局作用域,这样Ajax回调能直接调用它:
// 定义全局变量存储日历实例 var calendar; document.addEventListener('DOMContentLoaded', function () { var calendarEl = document.getElementById('rcalendar'); calendar = new FullCalendar.Calendar(calendarEl, { // 保留原配置内容不变 }); calendar.render(); });
2. 使用v5+正确的刷新方法
在Ajax的complete回调中,调用实例的refetchEvents()方法:
$.ajax({ type: "GET", url: "/OpsAdmin/SaveReminders/", data: {"groupId": '@Model.OpsAdminGroup', "adminId": '@Model.OpAdministrator', "targets": objectStr, "date": eventDate, "time": eventTime, "datetime": eventDateTime, "repeat": rpt, "mon": mon, "tue": tue, "wed": wed, "thu": thu, "fri": fri, "sat": sat, "sun": sun, "msg": msg }, success: function (result) { if (result.saved) { hideModal(); } }, complete: function() { // 检查实例存在后调用刷新方法 if (calendar) { calendar.refetchEvents(); } }, error: function (errorData) { onError(errorData); } });
额外注意事项
- 解决缓存问题:如果刷新后还是看不到新事件,可能是浏览器缓存了旧的JSON文件,可以在事件源URL后加时间戳参数:
eventSources: [ { url: '/Content/JSON/OpsReminders.json?t=' + new Date().getTime(), color: 'blue', textColor: 'white', editable: true } ] - 避免全局变量的替代方案:如果不想用全局变量,可以把实例绑定到DOM元素上:
// 初始化时 calendarEl.calendarInstance = calendar; // Ajax回调中 document.getElementById('rcalendar').calendarInstance.refetchEvents();
内容的提问来源于stack exchange,提问作者Alex22T
相关产品推荐
相关产品推荐

