Symfony+RiotJS中切换FullCalendar视图时如何动态更新事件
问题解决方案
你当前代码不生效的核心原因:初始化FullCalendar时传入的events: this.state.events是静态值传递,组件只会在初始化时读取一次该数组的内容,后续你手动修改Riot状态里的events变量,不会同步到FullCalendar的内部事件存储中;你注释掉的refetchEvents()仅对配置为异步接口/回调函数的events源生效,对静态数组无效。
方案1:直接调用日历实例API更新事件(改动最小)
不需要调整现有初始化逻辑,只需要在loadItems()方法里,把事件数据处理完成后,调用FullCalendar的内置方法替换事件源即可,替换后组件会自动重新渲染:
// 你原有处理events数组的逻辑不变,处理完成后加这两行 this.state.calendar.removeAllEvents(); // 清空当前所有旧事件 this.state.calendar.addEventSource(this.state.events); // 注入新拉取的事件集合
把这两行代码放在你注释写//after I gets the events I want to update the events of calendar here的位置即可,不需要额外调用render或者其他刷新方法。
方案2:使用FullCalendar异步事件源(官方推荐,逻辑更简洁)
去掉datesSet里手动触发loadItems()的逻辑,初始化时直接把events配置为异步回调函数,FullCalendar会在初始化、切换日期、切换视图时自动传入当前视图的时间范围,触发数据拉取,拉取完成后自动渲染事件,不需要手动操作实例更新:
调整后的初始化配置核心部分
this.state.calendar = new Calendar(calendarEl, { plugins: [ dayGridPlugin, timeGridPlugin, listPlugin ], initialView: 'dayGridMonth', headerToolbar: { left: 'prev,next today', center: 'title', right: 'dayGridMonth,timeGridWeek' }, buttonText: { today: 'Heute', month: 'Monat', week: 'Woche', day: 'Tag', }, // 替换原来的静态events配置,去掉datesSet里手动调用loadItems的逻辑 events: (fetchInfo, success, failure) => { this.state.loading = true; if (this.state.request) { this.state.request.abort(); } // fetchInfo自带当前视图的起止时间,不需要手动从dateProfile取值 const start = fetchInfo.start.toISOString().substring(0, 10); const end = fetchInfo.end.toISOString().substring(0, 10); updateSearchParam('begin', start); updateSearchParam('end', end); this.state.request = this.API.get('/events', this.getParams()); this.state.request.then(response => { this.state.items = response.data.items; this.state.filteredItems = null; this.state.total = response.data.total; const events = []; response.data.items.forEach( item => { events.push({ id: item.id, title: item.event.name, start: this.moment(item.begin).format('Y-MM-DD'), end: this.moment(item.end).format('Y-MM-DD'), backgroundColor: item.event.type.bgColor, borderColor: '#ffffff', textColor: this.getTextColor(item.event.type.bgColor), }); }); this.state.events = events; this.state.loading = false; this.state.request = null; this.update(); // 把处理好的事件传给success回调,FullCalendar自动渲染 success(events); }).catch(err => failure(err)); }, initialDate: getSearchParam('date', '') ? getSearchParam('date', '') : this.moment().format('Y-MM-DD'), });
这种写法下如果后续需要手动刷新事件,直接调用this.state.calendar.refetchEvents()就会自动重新触发上面的拉取逻辑,不需要自己写额外的更新代码。
内容的提问来源于stack exchange,提问作者Maksim
相关产品推荐
相关产品推荐

