FullCalendar 的资源时间轴和按资源分列的视图属于 Premium 版:商业应用需要付费购买许可证密钥。它的许可证页面列出了可以免费使用的情形:整个应用都采用 AGPL,或者由已注册的非营利组织使用。Needless UI 日程表在 MIT 许可证下同时提供这两项功能,还支持重复日程和 iCalendar 文件。本指南介绍如何把 Angular 应用从前者迁移到后者:哪些可以直接沿用,哪些不行,以及哪些数据需要转换。

文中使用 FullCalendar 7 的名称;版本 6 的名称与之不同时,写在方括号中。FullCalendar 的 Angular 连接器支持 Angular 16 到 22;Needless UI 需要 Angular 22。

功能对比

FullCalendar 与 Needless UI 日程表
功能FullCalendarNeedless UI
资源时间轴:每个会议室或每个人各占一行Premium支持:一天、一周或一个月
日视图和周视图中按资源分列Premium支持
月、周、日视图免费支持
拖动来移动日程或调整时长免费;拖到另一个资源上需要 Premium支持,也能拖到其他资源上。可以拖动结束端调整时长,开始端不行。
选择时间来创建日程免费支持,可用指针、长按或键盘
规则,例如不允许重叠免费:overlap 和 constraint 选项支持:只需一个 allow 函数,每次变更前都会询问它
用键盘移动日程、调整时长其无障碍文档中没有提到;文档只涉及 ARIA 标签和 Tab 焦点支持,并会向屏幕阅读器播报
重复日程免费,需配合 rrule 插件和库内置:RFC 5545 规则,但不支持 EXRULE、RDATE 和按小时重复的规则
iCalendar(.ics)免费:可读取订阅源可读写 .ics 文件
列表视图和年视图免费提供未来几天的日程列表;没有年视图
时区免费:本地时区、UTC 或命名时区不支持:按收到的时间原样显示
分组、嵌套或多列的资源Premium不支持:只有一列,由你的模板绘制
外部拖放、背景日程免费不支持
打印、虚拟渲染Premium不支持
框架Angular 16 到 22、React、Vue、纯 JavaScript 等Angular 22 和 React 19

选项对照

FullCalendar 的选项及其在 Needless UI 中的对应项
FullCalendarNeedless UI 日程表
<full-calendar [options]>、plugins、schedulerLicenseKey<nui-scheduler>,每个选项都有对应的输入属性;不需要插件,也不需要密钥
initialView: 'resourceTimelineDay'view="timeline",按周或按月显示时再加上 timelineSpan
initialView: 'timeGridWeek'view="week";[(view)] 支持双向绑定
resources、events[resources]、[events]
resourceId、extendedPropsresource、data
editable、selectableeditable、selectable
select(slotSelect):{ start, end, allDay, resource }
eventDrop、eventResize(eventChange):在你更新 events 之前,什么都不会移动
eventClick(eventClick)
eventOverlap、selectOverlap、eventAllow[allow]:用一个函数统一处理移动、调整时长和选择
slotDuration、snapDurationslotMinutes、snapMinutes,以分钟为单位
slotMinTime、slotMaxTime、scrollTimedayStart、dayEnd、scrollHour,以小时为单位
businessHours[businessHours],星期用 1(星期一)到 7 表示
datesSet(rangeChange)
eventContent、resourceCellContent [resourceLabelContent]nuiSchedulerEvent 和 nuiSchedulerResource 模板
locale、firstDaylocale(任意 BCP 47 语言标签)、firstDay(取值 1 到 7),以及用于界面文字的 labels

会议室预订时间轴的两种写法

会议室是资源,预订是日程。用户在会议室的行上拖动来预订,拖动预订来移动它,并且一个会议室同一时间只能有一个预订。使用 FullCalendar 7 及其 Premium 资源时间轴:

使用 Needless UI 日程表:

有两点不同。FullCalendar 会自行移动预订,再由应用同步这一变更;Needless UI 日程表只报告变更,你更新 events 后变更才会保留,因此你的数据始终是唯一的数据源。另外,allow 就是普通代码,无论变更来自指针还是键盘,每次变更前都会询问它,所以这条规则可以由你自己测试。会议室预订日历指南会一步步构建这个应用。

转换数据

FullCalendar 的数据与日程表要求的格式
FullCalendarNeedless UI
全天日程的 end 是日程结束后的那一天全天日程的 end 是它的最后一天:需要减去一天
时间可能以 Z 或偏移量(例如 +02:00)结尾不带偏移量的本地时间,例如 2026-11-02T09:30
星期用 0(星期日)到 6 表示,用于 businessHours 和 firstDay星期用 1(星期一)到 7(星期日)表示
时长用字符串表示,例如 '00:30'用数字表示:分钟数或小时数
资源先按 id 排序,再按标题排序资源按数组中的顺序排列
对象形式的 rrule,以及 exruleRFC 5545 字符串(例如 FREQ=WEEKLY;BYDAY=MO,FR),以及 exdate
时区,例如 America/New_York先换算时间。nuiSchedulerFromIcs(text, { timeZone }) 会在读取 .ics 文件时完成换算。

如果需要尚未支持的功能

如果你的应用依赖时区、资源分组、外部拖放或打印,这个日程表目前还无法取代 FullCalendar。欢迎就你需要的功能提交 issue。至于其他内容,日程表页面列出了每个输入属性、输出属性和示例。