如何在FullCalendar中实现事件的跨日期拖拽功能?
实现FullCalendar事件跨日期拖拽功能
没问题,我帮你一步步搞定这个拖拽功能,FullCalendar本身就自带这个能力,只需要做几个简单配置和回调处理就行:
1. 引入拖拽所需的交互插件
FullCalendar的拖拽功能依赖interaction插件,首先得确保你已经导入它:
import { FullCalendarComponent } from '@fullcalendar/angular'; import dayGridPlugin from '@fullcalendar/daygrid'; import timeGridPlugin from '@fullcalendar/timegrid'; import listPlugin from '@fullcalendar/list'; // 新增:导入交互插件 import interactionPlugin from '@fullcalendar/interaction';
然后更新你的calendarPlugins数组,把interaction插件加进去:
calendarPlugins = [dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin];
2. 开启日历的编辑权限
在你的<full-calendar>标签里添加[editable]="true"属性,这会允许事件被拖拽和调整大小,同时加上拖拽完成的监听回调:
<div class='app'> <div class='app-calendar' *ngIf="calendarVisible"> <full-calendar #calendar defaultView="dayGridMonth" [header]="{ left: 'prev,next today', center: 'title', right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek' }" [plugins]="calendarPlugins" [weekends]="calendarWeekends" [events]="calendarEvents" (dateClick)="handleDateClick($event)" <!-- 新增:开启编辑功能,允许拖拽 --> [editable]="true" <!-- 新增:监听事件拖拽完成的回调 --> (eventDrop)="handleEventDrop($event)" ></full-calendar> </div> </div>
3. 实现拖拽完成后的事件更新逻辑
在组件类里添加handleEventDrop方法,用来处理拖拽后的事件数据更新。这里要注意必须创建新的事件数组(Angular的变更检测需要依赖引用变化),不能直接修改原数组里的事件对象:
export class AppComponent { @ViewChild('calendar') calendarComponent: FullCalendarComponent; calendarPlugins = [dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin]; calendarVisible = true; calendarWeekends = true; calendarEvents = [ // 可以放一些测试事件方便调试 { id: '1', title: '测试事件', start: new Date(), allDay: true } ]; handleDateClick(arg) { if (confirm('Would you like to add an event to ' + arg.dateStr + ' ?')) { // 生成唯一id,方便后续拖拽匹配 const newEventId = Date.now().toString(); this.calendarEvents = this.calendarEvents.concat({ id: newEventId, title: 'New Event', start: arg.date, allDay: arg.allDay }); } } // 新增:处理事件拖拽完成 handleEventDrop(arg) { // 可选:加个确认框让用户确认拖拽操作 if (confirm(`确认将事件移至 ${arg.event.start.toISOString().split('T')[0]} 吗?`)) { // 生成新的事件数组,保持不可变性 this.calendarEvents = this.calendarEvents.map(event => { if (event.id === arg.event.id) { // 找到被拖拽的事件,更新其开始/结束时间 return { ...event, start: arg.event.start, end: arg.event.end // 如果是跨天事件,别忘了同步更新结束时间 }; } return event; }); } else { // 如果用户取消,恢复事件原来的位置 arg.revert(); } } }
额外小提示
- 给每个事件加上唯一的
id属性是最可靠的匹配方式,避免通过标题或时间匹配出现冲突。 - 如果你的事件是跨天的(带有
end属性),拖拽后FullCalendar会自动计算新的end时间,你只需要同步到数组里就行。 - 不需要确认框的话,直接去掉
confirm逻辑,直接更新数组即可。
内容的提问来源于stack exchange,提问作者CodeIgniter
相关产品推荐
相关产品推荐

