syncfusion-angular-calendar
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseImplementing Syncfusion Angular Calendar
Syncfusion Angular Calendar实现
A comprehensive guide for implementing the Syncfusion Essential JS 2 Calendar component in Angular applications. Learn to create date pickers, manage calendar views, handle events, and customize styling.
这是一份在Angular应用中实现Syncfusion Essential JS 2 Calendar组件的综合指南,你可以学习如何创建日期选择器、管理日历视图、处理事件以及自定义样式。
Calendar Overview
日历概览
The Syncfusion Angular Calendar component is a date selection widget that provides:
- Multiple calendar views: Month (default), Year, and Decade views with smooth navigation
- Date selection modes: Single date or multiple dates with property
isMultiSelection - Navigation control: method for programmatic view switching
navigateTo() - Date manipulation methods: and
addDate()for multi-selection managementremoveDate() - Comprehensive event system: change, created, navigated, renderDayCell, destroyed events
- Localization support: Locale-specific formatting, day header formats, first day of week
- Accessibility: Full WCAG 2.2 compliance, keyboard navigation, RTL support
- Rich customization: CSS classes, custom rendering, day cell customization
- Persistence: Optional state persistence across page reloads
Package:
@syncfusion/ej2-angular-calendarsSyncfusion Angular Calendar组件是一款日期选择小部件,提供以下能力:
- 多日历视图: 月视图(默认)、年视图、十年视图,支持流畅的导航切换
- 日期选择模式: 通过属性支持单选或多选日期
isMultiSelection - 导航控制: 提供方法实现编程式视图切换
navigateTo() - 日期操作方法: 提供和
addDate()方法管理多选日期removeDate() - 完善的事件系统: 支持change、created、navigated、renderDayCell、destroyed事件
- 本地化支持: 适配地区的格式、表头格式、一周起始日配置
- 无障碍功能: 完全符合WCAG 2.2标准,支持键盘导航、RTL布局
- 丰富的自定义能力: 支持CSS类配置、自定义渲染、日期单元格定制
- 状态持久化: 可选开启页面刷新后的状态保留能力
依赖包:
@syncfusion/ej2-angular-calendarsDocumentation Navigation
文档导航
Read the following references based on your specific needs:
你可以根据具体需求阅读以下参考文档:
Getting Started
快速入门
📄 Read: references/getting-started.md
- Package installation and module setup
- CSS theme imports and dependencies
- Basic calendar implementation
- Component initialization in Angular
- Running and testing setup
📄 阅读: references/getting-started.md
- 依赖包安装与模块配置
- CSS主题引入与依赖处理
- 基础日历实现
- Angular中组件初始化
- 运行与测试配置
Calendar Views
日历视图
📄 Read: references/calendar-views.md
- Month view (default display)
- Year view implementation
- Decade view implementation
- View navigation and transitions
- property usage
start - property for restricting views
depth
📄 阅读: references/calendar-views.md
- 月视图(默认展示)
- 年视图实现
- 十年视图实现
- 视图导航与过渡效果
- 属性用法
start - 用于限制视图层级的属性
depth
Date Selection
日期选择
📄 Read: references/date-selection.md
- Single date selection
- Multiple date selection ()
isMultiSelection - property for single dates
value - array for multiple dates
values - Min/max date constraints
- Date range validation
📄 阅读: references/date-selection.md
- 单日期选择
- 多日期选择()
isMultiSelection - 用于单选日期的属性
value - 用于多选日期的数组
values - 最小/最大日期约束
- 日期范围校验
Events & Methods
事件与方法
📄 Read: references/events-and-methods.md
- Event handlers (change, created, navigated, renderDayCell, destroyed)
- method for multi-selection
addDate() - method for multi-selection
removeDate() - for programmatic navigation
navigateTo() - to get active view
currentView() - to retrieve persistence data
getPersistData() - to destroy the calendar widget
destroy() - RenderDayCell for custom day styling
📄 阅读: references/events-and-methods.md
- 事件处理(change、created、navigated、renderDayCell、destroyed)
- 用于多选场景的方法
addDate() - 用于多选场景的方法
removeDate() - 用于编程式导航的
navigateTo() - 获取当前激活视图的
currentView() - 获取持久化数据的
getPersistData() - 销毁日历组件的
destroy() - 用于自定义日期样式的RenderDayCell
Calendar Navigation
日历导航
📄 Read: references/calendar-navigation.md
- Month navigation controls
- Year and Decade view switching
- Today button ()
showTodayButton - property
firstDayOfWeek - Week number display ()
weekNumber - Keyboard shortcuts and navigation
📄 阅读: references/calendar-navigation.md
- 月份导航控件
- 年视图与十年视图切换
- 今日按钮()
showTodayButton - 属性
firstDayOfWeek - 周数展示()
weekNumber - 键盘快捷键与导航
Accessibility & Globalization
无障碍与全球化
📄 Read: references/accessibility-and-globalization.md
- WCAG 2.2 and Section 508 compliance
- WAI-ARIA attributes and roles
- Keyboard navigation (arrows, enter, spacebar)
- Screen reader compatibility
- Localization (locale property)
- Day header formats (Short, Narrow, Abbreviated, Wide)
- RTL (Right-to-Left) support
📄 阅读: references/accessibility-and-globalization.md
- WCAG 2.2与第508节合规性
- WAI-ARIA属性与角色
- 键盘导航(方向键、回车、空格键)
- 屏幕阅读器兼容
- 本地化(locale属性)
- 日期表头格式(Short、Narrow、Abbreviated、Wide)
- RTL(从右到左)布局支持
Styling & Customization
样式与自定义
📄 Read: references/styling-and-customization.md
- CSS class customization (.e-calendar, .e-day-cell, .e-selected)
- Theme selection (Material, Bootstrap, Tailwind, Fabric)
- Dark mode implementation
- Custom day cell styling via renderDayCell
- Disabled dates styling
- Hover and focus states
📄 阅读: references/styling-and-customization.md
- CSS类自定义(.e-calendar、.e-day-cell、.e-selected)
- 主题选择(Material、Bootstrap、Tailwind、Fabric)
- 深色模式实现
- 通过renderDayCell自定义日期单元格样式
- 禁用日期样式
- hover与focus状态配置
API Reference
API参考
📄 Read: references/api-reference.md
- Complete property reference (value, values, isMultiSelection, min, max, start, depth, showTodayButton, locale, dayHeaderFormat, weekNumber, weekRule, firstDayOfWeek, cssClass, enableRtl, enabled, calendarMode, keyConfigs, enablePersistence, serverTimezoneOffset)
- All method signatures with examples (addDate, removeDate, navigateTo, currentView, getPersistData, destroy)
- Event argument types (ChangedEventArgs, NavigatedEventArgs, RenderDayCellEventArgs)
- Key configurations for keyboard shortcuts
- Calendar modes (Gregorian, Islamic)
- Return types and descriptions
📄 阅读: references/api-reference.md
- 完整属性参考(value、values、isMultiSelection、min、max、start、depth、showTodayButton、locale、dayHeaderFormat、weekNumber、weekRule、firstDayOfWeek、cssClass、enableRtl、enabled、calendarMode、keyConfigs、enablePersistence、serverTimezoneOffset)
- 所有方法签名与示例(addDate、removeDate、navigateTo、currentView、getPersistData、destroy)
- 事件参数类型(ChangedEventArgs、NavigatedEventArgs、RenderDayCellEventArgs)
- 键盘快捷键配置
- 日历模式(公历、伊斯兰历)
- 返回类型与说明
Quick Start Example
快速入门示例
typescript
// app.component.ts
import { Component } from '@angular/core';
import { ChangedEventArgs } from '@syncfusion/ej2-calendars';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// Single date selection
selectedDate: Date = new Date();
// Multiple date selection
selectedDates: Date[] = [
new Date(2026, 2, 15),
new Date(2026, 2, 20),
new Date(2026, 2, 25)
];
// Calendar configuration
minDate: Date = new Date(2020, 0, 1);
maxDate: Date = new Date(2030, 11, 31);
// Event handler
onCalendarChange(args: ChangedEventArgs): void {
console.log('Selected date:', args.value);
}
}html
<!-- app.component.html -->
<div style="padding: 20px; font-family: Arial, sans-serif;">
<h2>Single Date Selection</h2>
<ejs-calendar
[(ngModel)]="selectedDate"
[min]="minDate"
[max]="maxDate"
(change)="onCalendarChange($event)">
</ejs-calendar>
<p>Selected: {{ selectedDate | date:'medium' }}</p>
<h2>Multiple Date Selection</h2>
<ejs-calendar
[(ngModel)]="selectedDates"
[isMultiSelection]="true"
[showTodayButton]="true">
</ejs-calendar>
<p>Selected dates: {{ selectedDates.length }} dates</p>
</div>css
/* app.component.css */
@import '../node_modules/@syncfusion/ej2-base/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material3.css';
:host ::ng-deep .e-calendar {
margin: 20px 0;
}
:host ::ng-deep .e-selected {
background-color: #3f51b5;
color: white;
}typescript
// app.component.ts
import { Component } from '@angular/core';
import { ChangedEventArgs } from '@syncfusion/ej2-calendars';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// 单日期选择
selectedDate: Date = new Date();
// 多日期选择
selectedDates: Date[] = [
new Date(2026, 2, 15),
new Date(2026, 2, 20),
new Date(2026, 2, 25)
];
// 日历配置
minDate: Date = new Date(2020, 0, 1);
maxDate: Date = new Date(2030, 11, 31);
// 事件处理
onCalendarChange(args: ChangedEventArgs): void {
console.log('Selected date:', args.value);
}
}html
<!-- app.component.html -->
<div style="padding: 20px; font-family: Arial, sans-serif;">
<h2>Single Date Selection</h2>
<ejs-calendar
[(ngModel)]="selectedDate"
[min]="minDate"
[max]="maxDate"
(change)="onCalendarChange($event)">
</ejs-calendar>
<p>Selected: {{ selectedDate | date:'medium' }}</p>
<h2>Multiple Date Selection</h2>
<ejs-calendar
[(ngModel)]="selectedDates"
[isMultiSelection]="true"
[showTodayButton]="true">
</ejs-calendar>
<p>Selected dates: {{ selectedDates.length }} dates</p>
</div>css
/* app.component.css */
@import '../node_modules/@syncfusion/ej2-base/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material3.css';
:host ::ng-deep .e-calendar {
margin: 20px 0;
}
:host ::ng-deep .e-selected {
background-color: #3f51b5;
color: white;
}Common Patterns
常见实现模式
Pattern 1: Custom Date Range (Two Calendar Instances)
模式1:自定义日期范围(双日历实例)
The Calendar component does not have built-in range selection. Use two separate Calendar instances with / constraints and the event to implement a custom date range picker:
minmaxchangetypescript
export class AppComponent {
startDate: Date = new Date();
endDate: Date = new Date();
onStartDateChange(args: ChangedEventArgs): void {
this.startDate = args.value;
// Ensure end date is not before start date
if (this.endDate < this.startDate) {
this.endDate = this.startDate;
}
}
onEndDateChange(args: ChangedEventArgs): void {
this.endDate = args.value;
}
getDaysInRange(): number {
const timeDiff = this.endDate.getTime() - this.startDate.getTime();
return Math.ceil(timeDiff / (1000 * 3600 * 24)) + 1;
}
}html
<!-- Two separate Calendar instances for range selection -->
<ejs-calendar [(ngModel)]="startDate" (change)="onStartDateChange($event)"></ejs-calendar>
<ejs-calendar [(ngModel)]="endDate" [min]="startDate" (change)="onEndDateChange($event)"></ejs-calendar>Note: For a built-in range picker, use thecomponent instead.DateRangePicker
Calendar组件没有内置的范围选择能力,你可以使用两个独立的Calendar实例,配合/约束和事件实现自定义日期范围选择器:
minmaxchangetypescript
export class AppComponent {
startDate: Date = new Date();
endDate: Date = new Date();
onStartDateChange(args: ChangedEventArgs): void {
this.startDate = args.value;
// 确保结束日期不早于开始日期
if (this.endDate < this.startDate) {
this.endDate = this.startDate;
}
}
onEndDateChange(args: ChangedEventArgs): void {
this.endDate = args.value;
}
getDaysInRange(): number {
const timeDiff = this.endDate.getTime() - this.startDate.getTime();
return Math.ceil(timeDiff / (1000 * 3600 * 24)) + 1;
}
}html
<!-- 两个独立的Calendar实例实现范围选择 -->
<ejs-calendar [(ngModel)]="startDate" (change)="onStartDateChange($event)"></ejs-calendar>
<ejs-calendar [(ngModel)]="endDate" [min]="startDate" (change)="onEndDateChange($event)"></ejs-calendar>注意: 如果你需要内置的范围选择器,可以使用组件。DateRangePicker
Pattern 2: Calendar with Disabled Dates
模式2:带禁用日期的日历
Disable specific dates (weekends, holidays) using renderDayCell event:
typescript
export class AppComponent {
holidays: Date[] = [
new Date(2026, 11, 25), // Christmas
new Date(2026, 0, 1), // New Year
];
onRenderDayCell(args: RenderDayCellEventArgs): void {
// Disable weekends
if (args.date.getDay() === 0 || args.date.getDay() === 6) {
args.isDisabled = true;
}
// Disable holidays
if (this.isHoliday(args.date)) {
args.isDisabled = true;
}
}
private isHoliday(date: Date): boolean {
return this.holidays.some(holiday =>
holiday.toDateString() === date.toDateString()
);
}
}使用renderDayCell事件禁用指定日期(周末、节假日):
typescript
export class AppComponent {
holidays: Date[] = [
new Date(2026, 11, 25), // 圣诞节
new Date(2026, 0, 1), // 新年
];
onRenderDayCell(args: RenderDayCellEventArgs): void {
// 禁用周末
if (args.date.getDay() === 0 || args.date.getDay() === 6) {
args.isDisabled = true;
}
// 禁用节假日
if (this.isHoliday(args.date)) {
args.isDisabled = true;
}
}
private isHoliday(date: Date): boolean {
return this.holidays.some(holiday =>
holiday.toDateString() === date.toDateString()
);
}
}Pattern 3: Multi-Selection with Add/Remove
模式3:编程式控制多选日期的增删
Manage multiple selected dates programmatically:
typescript
export class AppComponent {
@ViewChild('calendar') calendarRef!: CalendarComponent;
selectedDates: Date[] = [];
addDateToSelection(date: Date): void {
// Check if already selected
if (!this.selectedDates.some(d =>
d.toDateString() === date.toDateString())) {
this.calendarRef.addDate(date);
}
}
removeDateFromSelection(date: Date): void {
this.calendarRef.removeDate(date);
}
clearAllDates(): void {
if (this.selectedDates.length > 0) {
this.calendarRef.removeDate(this.selectedDates);
}
}
}通过代码管理多个选中的日期:
typescript
export class AppComponent {
@ViewChild('calendar') calendarRef!: CalendarComponent;
selectedDates: Date[] = [];
addDateToSelection(date: Date): void {
// 检查是否已经选中
if (!this.selectedDates.some(d =>
d.toDateString() === date.toDateString())) {
this.calendarRef.addDate(date);
}
}
removeDateFromSelection(date: Date): void {
this.calendarRef.removeDate(date);
}
clearAllDates(): void {
if (this.selectedDates.length > 0) {
this.calendarRef.removeDate(this.selectedDates);
}
}
}Pattern 4: Year/Decade View Navigation
模式4:年/十年视图导航
Implement navigation to different calendar views:
typescript
export class AppComponent {
@ViewChild('calendar') calendarRef!: CalendarComponent;
navigateToYear(year: number): void {
const dateInYear = new Date(year, 0, 1);
this.calendarRef.navigateTo('Year', dateInYear);
}
navigateToDecade(startYear: number): void {
const dateInDecade = new Date(startYear, 0, 1);
this.calendarRef.navigateTo('Decade', dateInDecade);
}
getCurrentView(): string {
return this.calendarRef.currentView();
}
}实现跳转到不同日历视图的功能:
typescript
export class AppComponent {
@ViewChild('calendar') calendarRef!: CalendarComponent;
navigateToYear(year: number): void {
const dateInYear = new Date(year, 0, 1);
this.calendarRef.navigateTo('Year', dateInYear);
}
navigateToDecade(startYear: number): void {
const dateInDecade = new Date(startYear, 0, 1);
this.calendarRef.navigateTo('Decade', dateInDecade);
}
getCurrentView(): string {
return this.calendarRef.currentView();
}
}Pattern 5: Reactive Form Integration
模式5:响应式表单集成
Integrate Calendar with Angular Reactive Forms:
typescript
export class AppComponent implements OnInit {
dateForm: FormGroup;
constructor(private fb: FormBuilder) {
this.dateForm = this.fb.group({
eventDate: [new Date(), Validators.required],
eventName: ['', Validators.required]
});
}
ngOnInit(): void {
// Subscribe to date changes
this.dateForm.get('eventDate')?.valueChanges.subscribe(date => {
console.log('Event date changed:', date);
});
}
submitForm(): void {
if (this.dateForm.valid) {
console.log('Form values:', this.dateForm.value);
}
}
}html
<form [formGroup]="dateForm" (ngSubmit)="submitForm()">
<div>
<label for="eventDate">Event Date:</label>
<ejs-calendar
id="eventDate"
formControlName="eventDate">
</ejs-calendar>
</div>
<div>
<label for="eventName">Event Name:</label>
<input
id="eventName"
type="text"
formControlName="eventName">
</div>
<button type="submit" [disabled]="!dateForm.valid">Submit</button>
</form>将Calendar与Angular响应式表单集成:
typescript
export class AppComponent implements OnInit {
dateForm: FormGroup;
constructor(private fb: FormBuilder) {
this.dateForm = this.fb.group({
eventDate: [new Date(), Validators.required],
eventName: ['', Validators.required]
});
}
ngOnInit(): void {
// 监听日期变化
this.dateForm.get('eventDate')?.valueChanges.subscribe(date => {
console.log('Event date changed:', date);
});
}
submitForm(): void {
if (this.dateForm.valid) {
console.log('Form values:', this.dateForm.value);
}
}
}html
<form [formGroup]="dateForm" (ngSubmit)="submitForm()">
<div>
<label for="eventDate">活动日期:</label>
<ejs-calendar
id="eventDate"
formControlName="eventDate">
</ejs-calendar>
</div>
<div>
<label for="eventName">活动名称:</label>
<input
id="eventName"
type="text"
formControlName="eventName">
</div>
<button type="submit" [disabled]="!dateForm.valid">提交</button>
</form>Key Props Reference
核心属性参考
| Prop | Type | Description | Example |
|---|---|---|---|
| | Single selected date | |
| | Multiple selected dates | |
| | Enable multiple date selection | |
| | Minimum selectable date | |
| | Maximum selectable date | |
| | Initial view (Month/Year/Decade) | |
| | Maximum view level | |
| | Display today button | |
| | Culture/language code | |
| | Day format (Short/Narrow/Abbreviated/Wide) | |
| | Show week numbers | |
| | Rule for first week of year (FirstDay/FirstFullWeek/FirstFourDayWeek) | |
| | First day (0=Sunday, 1=Monday) | |
| | Custom CSS classes | |
| | Enable RTL layout | |
| | Enable/disable component | |
| | Calendar mode (Gregorian/Islamic) | |
| | Custom keyboard shortcuts | |
| | Persist state across page reloads | |
| | Server timezone offset for initial date processing | |
| 属性 | 类型 | 说明 | 示例 |
|---|---|---|---|
| | 单个选中日期 | |
| | 多个选中日期 | |
| | 开启多日期选择 | |
| | 最小可选日期 | |
| | 最大可选日期 | |
| | 初始视图(Month/Year/Decade) | |
| | 最深可访问视图层级 | |
| | 展示今日按钮 | |
| | 文化/语言编码 | |
| | 日期表头格式(Short/Narrow/Abbreviated/Wide) | |
| | 展示周数 | |
| | 一年第一周的判定规则(FirstDay/FirstFullWeek/FirstFourDayWeek) | |
| | 一周起始日(0=周日, 1=周一) | |
| | 自定义CSS类 | |
| | 开启RTL布局 | |
| | 启用/禁用组件 | |
| | 日历模式(Gregorian/Islamic) | |
| | 自定义键盘快捷键 | |
| | 开启页面刷新后状态持久化 | |
| | 用于初始日期处理的服务端时区偏移 | |
Common Use Cases
常见使用场景
Use Case 1: Event Booking System
- User selects start and end dates for event
- Disable past dates and weekends
- Solution: Combine min/max dates with renderDayCell for disable logic
- Reference: Calendar Views + Events & Methods
Use Case 2: Conference Schedule
- Display multiple highlighted dates (conference days)
- Allow year/decade navigation for planning
- Solution: Use isMultiSelection, highlight dates, navigate between views
- Reference: Date Selection + Calendar Navigation
Use Case 3: Accessible Booking Form
- Calendar integrated in form with keyboard navigation
- Screen reader compatible, WCAG 2.2 compliant
- Solution: Use Reactive Forms + Calendar events
- Reference: Accessibility & Globalization
Use Case 4: International Date Picker
- Support multiple languages and date formats
- Show RTL for Arabic, Hebrew
- Solution: Use locale property and localization
- Reference: Accessibility & Globalization
Use Case 5: Dynamic Date Constraints
- Disable dates based on business logic (availability, holidays)
- Update constraints based on user selections
- Solution: Use renderDayCell with dynamic logic
- Reference: Events & Methods + Calendar Views
场景1:活动预订系统
- 用户选择活动的开始和结束日期
- 禁用过去的日期和周末
- 解决方案:结合min/max日期与renderDayCell实现禁用逻辑
- 参考:日历视图 + 事件与方法
场景2:会议日程安排
- 高亮展示多个日期(会议举办日)
- 支持年/十年视图导航用于规划
- 解决方案:使用isMultiSelection、高亮日期、视图切换能力
- 参考:日期选择 + 日历导航
场景3:无障碍预订表单
- 日历集成在表单中,支持键盘导航
- 兼容屏幕阅读器,符合WCAG 2.2标准
- 解决方案:使用响应式表单 + Calendar事件
- 参考:无障碍与全球化
场景4:国际化日期选择器
- 支持多语言和多日期格式
- 为阿拉伯语、希伯来语提供RTL展示
- 解决方案:使用locale属性和本地化能力
- 参考:无障碍与全球化
场景5:动态日期约束
- 基于业务逻辑禁用日期(可预约日期、节假日)
- 根据用户选择更新约束规则
- 解决方案:使用renderDayCell配合动态逻辑
- 参考:事件与方法 + 日历视图
Related Skills
相关技能
- Implementing Syncfusion Angular Components - Main library guide for all Angular components
- DatePicker - Calendar popup with overlay functionality
- Scheduler - Advanced calendar with events and appointments
- DateRangePicker - Specialized date range selection component
Next Steps: Choose a reference guide above based on your specific needs, or explore the common patterns section for your use case.
- Syncfusion Angular组件实现 - 所有Angular组件的主库指南
- DatePicker - 带浮层的日历弹出选择器
- Scheduler - 支持事件和日程的高级日历
- DateRangePicker - 专门的日期范围选择组件
后续步骤: 根据你的具体需求选择上方的参考指南,或者查看常见模式部分适配你的使用场景。