Fullcalendar.getEvents()无法获取新增/已删除事件问题排查
问题:FullCalendar新增/删除事件后无法立即同步显示
技术背景
基于Vue、Kotlin、PostgreSQL技术栈开发应用,使用FullCalendar日历组件实现事件管理。用户通过弹窗填写事件信息,点击保存后触发后端API调用完成数据存储。
相关代码
HTML部分
<full-calendar v-if="calendarOptions" id="fullcalendar" :options="calendarOptions" tabindex="0" @rendered="storeCalendar" ></full-calendar>
核心脚本
const storeCalendar = (api: CalendarApi | undefined): void => { if (api) { calendar.value = api; } };
新增事件弹窗与数据处理
const openNewAgendaItemDialog = ( agendaItem: AgendaItem, allDay: boolean | undefined = undefined ) => { $q.dialog({ component: EventDetailsDialog, componentProps: { modelValue: agendaItem, isNew: true, zaak: zaak.value, isReadonly: isAgendaActueel.value, isAllDay: allDay, agendaItemTypes: determineAgendaItemsTypes(allDay), }, }).onOk(async (returnValue: AgendaItemDialogReturnType) => { switch (returnValue.type) { case "new": createAgendaItem(zaakId, returnValue) // 后端API调用 .then(() => { createConfirmation( "Succesvol opgeslagen", `De agenda-item is succesvol opgeslagen.` ); }) .then(reload); break; case "delete": throw new Error(`Unexpected object: ${returnValue}`); } }); }; const reload = (error: AxiosError | undefined | void = undefined): void => { if (!error || (!!error && error.response?.status !== HTTP_NOT_FOUND)) { console.log("reload: "); fetchEvents(zaakId, agendaId); // 后端拉取事件列表 fetchZaak(zaakId, true); fetchZaakWaarschuwingen(zaakId, true); inconsistentieCheck(true); } }; const inconsistentieCheck = (update: boolean): void => { calendar.value!.refetchEvents(); let eventArray = calendar.value!.getEvents(); eventArray.forEach((event) => {console.log("event.title: " + event.title)}) };
当前问题
- 新增事件:控制台日志无法立即看到刚添加的事件,只有更新其他事件后才会显示
- 删除事件:已删除的事件仍会出现在控制台日志中,更新其他事件后才会消失
问题原因
- 异步操作时序混乱:
createAgendaItem(写入后端)和fetchEvents(读取后端)都是异步操作,当前代码未确保写入完成后再执行读取,导致拉取的仍是旧数据。 - FullCalendar API异步特性忽略:
refetchEvents是异步方法,会触发FullCalendar重新从数据源拉取事件,但当前代码调用后立即执行getEvents,此时新事件还未完成加载,所以获取的仍是内存中的旧事件集合。
解决方法
1. 严格控制异步操作顺序
将reload改为异步函数,确保fetchEvents完成后再执行inconsistentieCheck;同时在openNewAgendaItemDialog中使用async/await替代链式then,避免回调嵌套导致的时序问题。
2. 等待refetchEvents完成后再获取事件
FullCalendar的refetchEvents返回Promise,需等待其resolve后再调用getEvents,确保拿到最新的事件集合。
修改后的代码示例
// 重构openNewAgendaItemDialog的onOk逻辑 .onOk(async (returnValue: AgendaItemDialogReturnType) => { switch (returnValue.type) { case "new": try { await createAgendaItem(zaakId, returnValue); createConfirmation("Succesvol opgeslagen", `De agenda-item is succesvol opgeslagen.`); await reload(); // 等待reload完成 } catch (err) { // 处理错误 } break; case "delete": throw new Error(`Unexpected object: ${returnValue}`); } }); // 重构reload为异步函数 const reload = async (error: AxiosError | undefined | void = undefined): Promise<void> => { if (!error || (!!error && error.response?.status !== HTTP_NOT_FOUND)) { console.log("reload: "); // 等待所有后端请求完成 await Promise.all([ fetchEvents(zaakId, agendaId), fetchZaak(zaakId, true), fetchZaakWaarschuwingen(zaakId, true) ]); await inconsistentieCheck(true); // 等待事件检查完成 } }; // 重构inconsistentieCheck为异步函数 const inconsistentieCheck = async (update: boolean): Promise<void> => { await calendar.value!.refetchEvents(); // 等待事件重新拉取完成 const eventArray = calendar.value!.getEvents(); eventArray.forEach((event) => {console.log("event.title: " + event.title)}) };
额外优化建议
- 确保
fetchEvents内部是正确的异步实现,返回Promise,这样Promise.all才能正确等待其完成。 - 如果FullCalendar是通过
events选项绑定数据源,可直接更新数据源数组并触发响应式更新,无需依赖refetchEvents,能更高效地同步显示最新事件。
内容的提问来源于stack exchange,提问作者user2363969
相关产品推荐
相关产品推荐

