You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 22:04:07