mcpField
S
syncfusion-angular-calendars

syncfusion-angular-calendars

github.com/syncfusion开发0177 次安装1 周前更新
代码仓库

关于 syncfusion-angular-calendars

面向 Angular 开发者的 Syncfusion Calendar 和 DatePicker 实现指南,涵盖日期选择、导航、事件、表单集成与样式定制。也说明多语言、无障碍和日期约束等配置方式。

主要功能

  1. 01单日期与多日期选择
  2. 02月、年和十年视图导航
  3. 03事件处理与日期管理方法
  4. 04本地化、RTL 与键盘操作
  5. 05表单集成和日期范围校验
  6. 06自定义日期单元格样式

适用场景

  1. 01在活动预订表单中设置日期范围
  2. 02显示并选择多个会议日期
  3. 03构建支持键盘操作的日期表单
  4. 04为不同地区配置日期格式

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/syncfusion/angular-ui-components-skills --skill syncfusion-angular-calendars

安装后在 Claude Code 中输入/syncfusion-angular-calendars确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
calendar-accessibility-and-globalization.md
calendar-api-reference.md
calendar-date-selection.md
calendar-events-and-methods.md
calendar-getting-started.md
calendar-navigation.md
calendar-styling-and-customization.md
calendar-views.md
datepicker-accessibility-and-forms.md
datepicker-advanced-patterns.md
datepicker-date-formats-and-parsing.md
datepicker-date-range-and-validation.md
datepicker-date-views-and-navigation.md
datepicker-getting-started.md
datepicker-globalization-and-localization.md
datepicker-masking-and-editing.md
datepicker-styling-and-customization.md
datepicker-testing-guide.md
daterangepicker-api-reference.md
daterangepicker-date-formatting-and-constraints.md
daterangepicker-date-range-selection.md
daterangepicker-events-and-methods.md
daterangepicker-getting-started.md
daterangepicker-globalization-and-localization.md
daterangepicker-keyboard-navigation-and-accessibility.md
daterangepicker-preset-ranges.md
daterangepicker-styling-and-customization.md
datetimepicker-accessibility-and-globalization.md
datetimepicker-advanced-features.md
datetimepicker-api-reference.md

详细介绍

实现 Syncfusion Angular 日历

日历

本指南全面介绍如何在 Angular 应用中实现 Syncfusion Essential JS 2 Calendar 组件。了解如何创建日期选择器、管理日历视图、处理事件以及自定义样式。

日历概述

Syncfusion Angular Calendar 组件是一种日期选择控件,提供以下功能:

  • 多种日历视图: 月(默认)、年和十年视图,并支持流畅导航
  • 日期选择模式: 使用 isMultiSelection 属性选择单个日期或多个日期
  • 导航控制: 使用 navigateTo() 方法以编程方式切换视图
  • 日期操作方法: 使用 addDate() 和 removeDate() 管理多选
  • 全面的事件系统: change、created、navigated、renderDayCell、destroyed 事件
  • 本地化支持: 特定区域设置的格式、日期标题格式、每周首日
  • 无障碍访问: 完全符合 WCAG 2.2 标准,支持键盘导航和 RTL
  • 丰富的自定义选项: CSS 类、自定义渲染、日期单元格自定义
  • 持久化: 可选择在页面重新加载后保留状态

软件包: @syncfusion/ej2-angular-calendars

文档导航

根据具体需求阅读以下参考资料:

入门指南

📄 阅读: references/getting-started.md

  • 软件包安装和模块设置
  • CSS 主题导入和依赖项
  • 基本日历实现
  • Angular 中的组件初始化
  • 运行和测试设置
日历视图

📄 阅读: references/calendar-views.md

  • 月视图(默认显示)
  • 年视图实现
  • 十年视图实现
  • 视图导航和切换
  • start 属性的用法
  • 用于限制视图的 depth 属性
日期选择

📄 阅读: references/date-selection.md

  • 单日期选择
  • 多日期选择(isMultiSelection)
  • 用于单个日期的 value 属性
  • 用于多个日期的 values 数组
  • 日期最小值/最大值限制
  • 日期范围验证
事件和方法

📄 阅读: references/events-and-methods.md

  • 事件处理程序(change、created、navigated、renderDayCell、destroyed)
  • 用于多选的 addDate() 方法
  • 用于多选的 removeDate() 方法
  • 用于编程式导航的 navigateTo()
  • 用于获取当前视图的 currentView()
  • 用于获取持久化数据的 getPersistData()
  • 用于销毁日历控件的 destroy()
  • 使用 RenderDayCell 自定义日期样式
日历导航

📄 阅读: references/calendar-navigation.md

  • 月份导航控件
  • 年视图和十年视图切换
  • “今天”按钮(showTodayButton)
  • firstDayOfWeek 属性
  • 周数显示(weekNumber)
  • 键盘快捷键和导航
无障碍访问和全球化

📄 阅读: references/accessibility-and-globalization.md

  • 符合 WCAG 2.2 和 Section 508 标准
  • WAI-ARIA 属性和角色
  • 键盘导航(方向键、回车键、空格键)
  • 兼容屏幕阅读器
  • 本地化(locale 属性)
  • 日期标题格式(短、窄、缩写、完整)
  • RTL(从右到左)支持
样式和自定义

📄 阅读: references/styling-and-customization.md

  • CSS 类自定义(.e-calendar、.e-day-cell、.e-selected)
  • 主题选择(Material、Bootstrap、Tailwind、Fabric)
  • 深色模式实现
  • 通过 renderDayCell 自定义日期单元格样式
  • 禁用日期的样式
  • 悬停和焦点状态
API 参考

📄 阅读: 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)
  • 键盘快捷键的按键配置
  • 日历模式(Gregorian、Islamic)
  • 返回类型及说明
快速入门示例
// 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);
  }
}

<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>
/* 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;
}
常见模式
模式 1:自定义日期范围(两个日历实例)

Calendar 组件没有内置的范围选择功能。使用两个独立的 Calendar 实例,结合 min/max 约束和 change 事件,实现自定义日期范围选择器:

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;
  }
}

<ejs-calendar [(ngModel)]="startDate" (change)="onStartDateChange($event)"></ejs-calendar>
<ejs-calendar [(ngModel)]="endDate" [min]="startDate" (change)="onEndDateChange($event)"></ejs-calendar>
模式 2:禁用日期的日历

使用 renderDayCell 事件禁用特定日期(周末、节假日):

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()
    );
  }
}
模式 3:使用添加/移除功能进行多选

以编程方式管理多个选中的日期:

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);
    }
  }
}
模式 4:年份/十年视图导航

实现导航到不同日历视图的功能:

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();
  }
}
模式 5:响应式表单集成

将 Calendar 与 Angular Reactive Forms 集成:

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);
    }
  }
}
<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>
关键属性参考
属性类型说明示例
valueDate单个选中的日期[value]="selectedDate"
valuesDate[]多个选中的日期[values]="selectedDates"
isMultiSelectionboolean启用多日期选择[isMultiSelection]="true"
minDate可选日期的下限[min]="minDate"
maxDate可选日期的上限[max]="maxDate"
startCalendarView初始视图(月/年/十年)start="Month"
depthCalendarView最大视图级别depth="Month"
showTodayButtonboolean显示“今天”按钮[showTodayButton]="true"
localestring区域/语言代码locale="fr-FR"
dayHeaderFormatDayHeaderFormats星期格式(短/窄/缩写/完整)dayHeaderFormat="Abbreviated"
weekNumberboolean显示周数[weekNumber]="true"
weekRuleWeekRule一年中第一周的规则(FirstDay/FirstFullWeek/FirstFourDayWeek)weekRule="FirstFourDayWeek"
firstDayOfWeeknumber一周的第一天(0=周日,1=周一)[firstDayOfWeek]="1"
cssClassstring自定义 CSS 类cssClass="custom-calendar"
enableRtlboolean启用 RTL 布局[enableRtl]="true"
enabledboolean启用/禁用组件[enabled]="true"
calendarModeCalendarType日历模式(Gregorian/Islamic)calendarMode="Islamic"
keyConfigs{ [key: string]: string }自定义键盘快捷键[keyConfigs]="keyConfigs"
enablePersistenceboolean在页面重新加载后保留状态[enablePersistence]="true"
serverTimezoneOffsetnumber | null用于初始日期处理的服务器时区偏移量[serverTimezoneOffset]="330"
常见用例

用例 1:活动预订系统

  • 用户为活动选择开始和结束日期
  • 禁用过去的日期和周末
  • 解决方案:结合使用最小/最大日期与 renderDayCell 实现禁用逻辑
  • 参考:日历视图 + 事件与方法

用例 2:会议日程

  • 显示多个高亮日期(会议日)
  • 支持按年份/十年导航以便规划
  • 解决方案:使用 isMultiSelection、高亮日期并在不同视图之间导航
  • 参考:日期选择 + 日历导航

用例 3:无障碍预订表单

  • 在表单中集成日历并支持键盘导航
  • 兼容屏幕阅读器,符合 WCAG 2.2 标准
  • 解决方案:使用 Reactive Forms + 日历事件
  • 参考:无障碍与全球化

用例 4:国际化日期选择器

  • 支持多种语言和日期格式
  • 为阿拉伯语、希伯来语显示 RTL 布局
  • 解决方案:使用 locale 属性和本地化功能
  • 参考:无障碍与全球化

用例 5:动态日期限制

  • 根据业务逻辑(可用情况、节假日)禁用日期
  • 根据用户选择更新限制
  • 解决方案:使用 renderDayCell 实现动态逻辑
  • 参考:事件与方法 + 日历视图

DatePicker

Syncfusion Angular DatePicker 提供直观易用的日历界面,用于选择单个日期,并支持格式化、验证、日期范围以及完整的无障碍功能(WCAG 2.2)。本技能将引导你了解所有基本实现模式和高级功能。

组件概述

DatePicker 将文本输入框与弹出式日历选择器结合起来。用户可以直接输入日期,也可以通过日历进行选择。主要功能:

  • 日期选择:通过日历 UI 或文本输入框选择
  • 多种日期格式(适配区域设置、自定义模式)
  • 日期范围验证(最小值/最大值、严格模式)
  • 输入掩码,帮助用户输入日期
  • 多种日历视图(月 → 年 → 十年导航)
  • 无障碍功能(WCAG 2.2、ARIA、键盘支持、RTL)
  • 国际化(CLDR 数据、100 多种区域设置)
  • 表单集成(FormValidator、响应式表单、模板驱动表单)
文档与导航指南
入门

📄 阅读:references/getting-started.md

  • 面向 Angular 21+ 独立架构的安装与设置
  • 软件包依赖项和导入
  • DatePicker 基本实现
  • CSS 主题导入
  • 最简可运行示例
日期格式与解析

📄 阅读:references/date-formats-and-parsing.md

  • 标准日期格式模式(yyyy-MM-dd、dd/MM/yyyy 等)
  • 区域设置专属的默认格式
  • 创建自定义日期格式
  • parseDate 和 formatDate 方法
  • 动态切换格式
日期范围与验证

📄 阅读:references/date-range-and-validation.md

  • 设置日期范围限制(min/max 属性)
  • 处理超出范围的日期和错误状态
  • 空日期验证和 strictMode
  • 检测无效日期
  • 实际应用中的日期限制模式
日期视图与导航

📄 阅读:references/date-views-and-navigation.md

  • 配置起始视图(月/年/十年)
  • 限制深度视图以限制选择范围
  • 在不同日历视图之间导航
  • 月份和年份选择模式
  • 不同视图配置的适用场景
掩码与编辑

📄 阅读: references/masking-and-editing.md

  • 启用日期输入掩码,引导用户输入
  • 基于日期格式的掩码模式
  • 掩码输入中的键盘导航(上/下/左/右箭头)
  • 自定义掩码占位符
  • 支持区域设置的掩码占位文本
样式与自定义

📄 阅读: references/styling-and-customization.md

  • 自定义包装元素和输入元素的 CSS
  • DatePicker 图标的样式与自定义
  • 移动设备上的全屏模式
  • 占位符和只读状态自定义
  • 深色模式与 Theme Studio 集成
无障碍与表单

📄 阅读: references/accessibility-and-forms.md

  • 符合 WCAG 2.2 和无障碍标准
  • ARIA 属性(aria-expanded、aria-disabled、aria-activedescendant)
  • 键盘导航支持(箭头键、Enter、Escape)
  • 屏幕阅读器支持和语义化标记
  • 集成 FormValidator 进行日期验证
  • 响应式表单和模板驱动表单模式
  • 自定义验证规则
全球化与本地化

📄 阅读: references/globalization-and-localization.md

  • 加载 CLDR 数据,实现特定区域的格式化
  • 区域设置感知的日期解析和格式化
  • 区域设置配置和 L10n 设置
  • 按区域设置确定每周第一天(周数据)
  • 支持从右到左(RTL)的语言
  • 多语言示例
  • 支持时区的日期处理
测试与质量保证

📄 阅读: references/testing-guide.md

  • 使用 Jasmine/Karma 进行单元测试:解析、验证器、事件
  • 使用 Cypress 进行 E2E 测试:日历交互、表单流程
  • 使用 axe-core 进行无障碍测试,并检查键盘导航
高级模式

📄 阅读: references/advanced-patterns.md

  • 级联日期选择器(依赖可用性)
  • 由业务逻辑驱动的动态日期范围
  • 禁用/不可用日期及重复日期处理
  • 高级场景的测试和验证模式
快速入门示例

在 Angular 21+ 独立组件中实现基础 DatePicker:

import { Component } from '@angular/core';
import { DatePickerModule } from '@syncfusion/ej2-angular-calendars';

@Component({
  selector: 'app-datepicker-demo',
  standalone: true,
  imports: [DatePickerModule],
  template: `
    <ejs-datepicker
      placeholder="Select date"
      [(ngModel)]="selectedDate"
      (change)="onDateChange($event)">
    </ejs-datepicker>
    <p>Selected: {{ selectedDate | date:'fullDate' }}</p>
  `
})
export class DatePickerDemoComponent {
  selectedDate: Date | null = null;

  onDateChange(event: any) {
    console.log('Date changed:', event.value);
  }
}

设置步骤:

  1. 安装 @syncfusion/ej2-angular-calendars 包
  2. 在组件中导入 DatePickerModule
  3. 添加带有属性的 <ejs-datepicker> 元素
  4. 使用 [(ngModel)](双向绑定)绑定到组件变量

运行效果:

  • DatePicker 会显示日历图标
  • 单击以打开弹出日历
  • 从日历中选择日期或直接输入
  • 所选日期会更新组件变量
  • 选择日期时会触发 change 事件
常见模式
1. 日期范围验证

限制用户只能选择指定起止日期之间的日期:

minDate = new Date(2024, 0, 1);  // Jan 1, 2024
maxDate = new Date(2024, 11, 31); // Dec 31, 2024
<ejs-datepicker
  [min]="minDate"
  [max]="maxDate"
  placeholder="Select date in 2024">
</ejs-datepicker>

适用场景: 航班预订、酒店预订、预约安排

2. 自定义日期格式

以应用特定格式显示日期:

dateFormat = 'dd/MM/yyyy';  // European format
<ejs-datepicker
  [format]="dateFormat"
  placeholder="DD/MM/YYYY">
</ejs-datepicker>
3. 掩码日期输入

通过可视化掩码和箭头键导航引导用户输入:

<ejs-datepicker
  [enableMask]="true"
  [maskPlaceholder]="'day'"
  format="dd/MM/yyyy">
</ejs-datepicker>

键盘导航: 上/下箭头可递增/递减各段,左/右箭头可在各段之间导航

4. 日期范围选择(带最小值/最大值)

在预订场景中禁止选择过去的日期:

minDate = new Date(); // Today
maxDate: Date;

constructor() {
  // Set max to 90 days from today
  this.maxDate = new Date();
  this.maxDate.setDate(this.maxDate.getDate() + 90);
}
5. 响应式表单集成

带有响应式表单验证的 DatePicker:

import { ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms';

export class FormComponent {
  form = this.fb.group({
    birthDate: [null, [Validators.required]],
  });

  constructor(private fb: FormBuilder) {}
}
<form [formGroup]="form">
  <ejs-datepicker
    formControlName="birthDate"
    placeholder="Birth date">
  </ejs-datepicker>
  <span *ngIf="form.get('birthDate')?.hasError('required')">
    Birth date is required
  </span>
</form>
API 参考(属性、方法、事件)
属性
属性类型说明
allowEditboolean文本框是否可编辑(默认为 true)
calendarModeCalendarType日历类型(例如,公历、伊斯兰历)
cssClassstring用于自定义样式的根 CSS 类
dayHeaderFormatDayHeaderFormats日期标题格式(Short/Narrow/Abbreviated/Wide)
depthCalendarView允许的最深日历视图(Month/Year/Decade)
enableMaskboolean启用带掩码的日期输入
enablePersistenceboolean在重新加载期间保留组件状态
enableRtlboolean启用从右到左的渲染
enabledboolean启用或禁用组件(设置为 false 可禁用)
firstDayOfWeeknumber一周的第一天(0-6)
floatLabelTypeFloatLabelType|string输入框的浮动标签行为
formatstring|FormatObject值的显示格式
fullScreenModeboolean在移动设备上以全屏模式显示弹出窗口
htmlAttributes{ [key:string]: string }根元素的其他 HTML 属性
inputFormatsstring[]|FormatObject[]可接受的解析输入格式
keyConfigs{ [key:string]: string }自定义按键操作映射
localestring覆盖全局区域设置(例如,'en-US')
maskPlaceholderMaskPlaceholderModel带掩码输入的占位文本
maxDate可选日期的上限
minDate可选日期的下限
openOnFocusboolean输入框获得焦点时打开弹出窗口
placeholderstring输入框占位文本
readonlyboolean将输入框设为只读(禁止输入)
serverTimezoneOffsetnumber服务器时区偏移量(分钟,可选)
showClearButtonboolean显示/隐藏清除图标
showTodayButtonboolean显示/隐藏弹出窗口中的“今天”按钮
startCalendarView弹出窗口打开时的初始视图
strictModeboolean强制执行严格解析/验证
valueDate选定的日期值
weekNumberboolean在日历中显示周数
weekRuleWeekRule年份第一周的规则
widthnumber|string组件宽度
zIndexnumber弹出窗口的 Z-index
方法
  • currentView() — 返回当前日历视图名称
  • destroy() — 销毁组件实例
  • focusIn() — 聚焦输入框
  • focusOut() — 使输入框失去焦点
  • getPersistData() — 返回持久化属性字符串
  • hide() — 隐藏日历弹出窗口
  • navigateTo(view: CalendarView, date?: Date) — 导航到指定视图/日期
  • removeDate(dates: Date|Date[]) — 从值中移除日期
  • show() — 显示日历弹出窗口
事件
  • blur — 输入框失去焦点时触发
  • change — 值发生变化时触发(提供 ChangedEventArgs)
  • cleared — 使用清除按钮时触发
  • close — 弹出窗口关闭时触发(可阻止)
  • created — 组件创建生命周期事件
  • destroyed — 组件销毁生命周期事件
  • focus — 输入框获得焦点时触发
  • navigated — 日历导航到其他视图时触发
  • open — 弹出窗口打开时触发(可阻止)
  • renderDayCell — 每个日期单元格渲染时触发(可用于禁用/自定义单元格)
常见用例
  1. 生日/出生日期选择: 使用最小值/最大值验证、带掩码的输入,以及十年视图起始页以便快速选择年份
  2. 会议日程安排: 日期范围(今天 + 90 天)、自定义工作日验证、表单集成
  3. 酒店/航班预订: 最小值/最大值日期、双向日期绑定,以及带验证的响应式表单
  4. 申请表单: 出生日期、许可证到期日、预约日期,并符合无障碍要求
  5. 国际化应用: 区域设置感知格式、RTL 支持、特定文化的日历

DateRangePicker

在 Angular 应用中实现 Syncfusion Essential JS 2 DateRangePicker 组件的综合指南。了解如何创建日期范围选择器、处理范围选择、管理事件和自定义样式。

DateRangePicker 概览

Syncfusion Angular DateRangePicker 组件是一款专用的日期选择控件,提供以下功能:

  • 双日历显示: 同步日历,供用户选择开始日期和结束日期
  • 预设范围: 预定义选项,例如“最近 7 天”“本月”“上月”“自定义”
  • 范围验证: 最小/最大日期、禁用范围、必需的范围长度
  • 日期格式: 可自定义日期格式,支持分隔符和格式模式
  • 事件系统: created、destroyed、change、select、rangeSelected、open、close、renderDayCell 事件
  • 键盘快捷键: 支持 Tab、方向键、Enter、Escape,提供完整的键盘无障碍支持
  • 本地化支持: 特定区域设置的格式、日期标题和月份名称
  • 无障碍功能: 完全符合 WCAG 2.2 标准,支持 ARIA 属性和屏幕阅读器
  • 丰富的自定义选项: CSS 类、自定义模板、日期单元格渲染
  • 移动设备优化: 触控友好界面、响应式设计、全屏模式

软件包: @syncfusion/ej2-angular-calendars

文档导航

根据具体需求阅读以下参考文档:

入门

📄 阅读: references/getting-started.md

  • 软件包安装和模块设置
  • CSS 主题导入和依赖项
  • 基本的 DateRangePicker 实现
  • 在 Angular 中初始化组件
  • 开始日期和结束日期配置
  • 运行和测试设置
日期范围选择

📄 阅读: references/date-range-selection.md

  • 单击选择范围
  • 依次选择日期(先单击开始日期,再单击结束日期)
  • 日期范围值绑定(startDate、endDate 属性)
  • 最小/最大日期限制
  • 范围验证和错误处理
  • 禁用日期范围
  • 清除选择
预设范围

📄 阅读: references/preset-ranges.md

  • 预定义范围选项(最近 7 天、上月等)
  • 自定义预设配置
  • 以编程方式应用预设
  • 动态生成预设
  • 预设更改事件
  • 将预设与限制条件结合使用
事件和方法

📄 阅读: references/events-and-methods.md

  • 事件处理程序(change、select、rangeSelected、open、close)
  • 范围选择事件详情(startDate、endDate、daySpan)
  • 编程方法(show()、hide()、getSelectedRange())
  • created 和 destroyed 生命周期事件
  • 使用 RenderDayCell 自定义样式
  • 方法返回类型和参数
日期格式和限制条件

📄 阅读: references/date-formatting-and-constraints.md

  • 日期格式模式和分隔符
  • 多种格式支持(format 和 inputFormats)
  • 最小/最大日期限制
  • 最小/最大天数验证
  • 禁用日期配置
  • 格式错误处理
  • 特定区域设置的格式
键盘导航和无障碍功能

📄 阅读: references/keyboard-navigation-and-accessibility.md

  • Tab 和 Shift+Tab 导航
  • 使用方向键浏览日期
  • 使用 Enter 选择并确认范围
  • 使用 Escape 关闭选择器
  • Alt 键快捷键
  • 兼容屏幕阅读器
  • ARIA 标签和角色
  • 符合 WCAG 2.2 AA 标准
  • 焦点管理
样式和自定义

📄 阅读: references/styling-and-customization.md

  • CSS 类自定义(.e-daterangepicker、.e-calendar、.e-range-header)
  • 主题选择(Material、Bootstrap、Tailwind、Fabric)
  • 深色模式实现
  • 使用 renderDayCell 自定义日期单元格样式
  • 禁用日期样式
  • 预设按钮样式
  • 悬停和焦点状态
  • 响应式布局自定义
全球化与本地化

📄 阅读: references/globalization-and-localization.md

  • 用于日期格式设置的 Locale 属性
  • RTL(从右向左)支持阿拉伯语、希伯来语
  • 星期标题格式(短、窄、缩写、完整)
  • 月份名称和星期名称本地化
  • 自定义 Locale 支持
  • 时区处理
  • 日期格式本地化
API 参考

📄 阅读: references/api-reference.md

  • 完整的属性参考及说明
  • 所有方法签名及返回类型
  • 事件参数类型和结构
  • 类型接口(RangeEventArgs、NavigatingEventArgs 等)
  • CSS 类和样式钩子
  • 浏览器支持矩阵
快速入门示例
// app.component.ts
import { Component } from '@angular/core';
import { RangeEventArgs } from '@syncfusion/ej2-calendars';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  // Date range properties
  startDate: Date = new Date(2026, 2, 1);  // March 1, 2026
  endDate: Date = new Date(2026, 2, 31);   // March 31, 2026
  
  // Constraints
  minDate: Date = new Date(2020, 0, 1);
  maxDate: Date = new Date(2030, 11, 31);
  
  // Range display
  selectedRange: string = '';
  
  // Event handler
  onRangeChange(args: RangeEventArgs): void {
    console.log('Start Date:', args.startDate);
    console.log('End Date:', args.endDate);
    console.log('Days in range:', args.daySpan);
    this.updateRangeDisplay();
  }
  
  updateRangeDisplay(): void {
    if (this.startDate && this.endDate) {
      const start = this.startDate.toLocaleDateString();
      const end = this.endDate.toLocaleDateString();
      this.selectedRange = `${start} - ${end}`;
    }
  }
}

<div style="padding: 20px; font-family: Arial, sans-serif;">
  <h2>DateRangePicker Example</h2>
  
  <div style="margin-bottom: 20px;">
    <label for="dateRange">Select Date Range:</label>
    <ejs-daterangepicker 
      id="dateRange"
      placeholder="Select a date range"
      [startDate]="startDate"
      [endDate]="endDate"
      [min]="minDate"
      [max]="maxDate"
      (change)="onRangeChange($event)">
    </ejs-daterangepicker>
  </div>
  
  <div *ngIf="selectedRange" style="padding: 10px; background-color: #f0f0f0;">
    <p><strong>Selected Range:</strong> {{ selectedRange }}</p>
  </div>
</div>
/* app.component.css */
@import '../node_modules/@syncfusion/ej2-base/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material3.css';

:host ::ng-deep .e-daterangepicker {
  margin: 10px 0;
  width: 100%;
}

:host ::ng-deep .e-range-header {
  background-color: #3f51b5;
  color: white;
}
常见模式
模式 1:预设日期范围

用于常见日期范围的快速选择按钮:

export class AppComponent {
  presets: any[] = [
    { label: 'Today', start: new Date(), end: new Date() },
    { label: 'Last 7 Days', start: this.getDateDaysAgo(7), end: new Date() },
    { label: 'Last 30 Days', start: this.getDateDaysAgo(30), end: new Date() },
    { label: 'This Month', start: this.getFirstDayOfMonth(), end: new Date() },
    { label: 'Last Month', start: this.getFirstDayOfLastMonth(), end: this.getLastDayOfLastMonth() }
  ];
  
  startDate: Date = new Date();
  endDate: Date = new Date();
  
  selectPreset(preset: any): void {
    this.startDate = preset.start;
    this.endDate = preset.end;
  }
  
  private getDateDaysAgo(days: number): Date {
    const date = new Date();
    date.setDate(date.getDate() - days);
    return date;
  }
  
  private getFirstDayOfMonth(): Date {
    return new Date(new Date().getFullYear(), new Date().getMonth(), 1);
  }
  
  private getFirstDayOfLastMonth(): Date {
    const date = new Date();
    return new Date(date.getFullYear(), date.getMonth() - 1, 1);
  }
  
  private getLastDayOfLastMonth(): Date {
    const date = new Date();
    return new Date(date.getFullYear(), date.getMonth(), 0);
  }
}
<div>
  <div style="margin-bottom: 10px;">
    <button *ngFor="let preset of presets" 
            (click)="selectPreset(preset)"
            style="margin-right: 5px; padding: 8px 12px;">
      {{ preset.label }}
    </button>
  </div>
  
  <ejs-daterangepicker 
    [startDate]="startDate"
    [endDate]="endDate">
  </ejs-daterangepicker>
</div>
模式 2:日期范围验证

使用自定义约束验证日期范围:

export class AppComponent {
  @ViewChild('daterangepicker') drp!: DateRangePickerComponent;
  
  startDate: Date = new Date();
  endDate: Date = new Date();
  rangeError: string = '';
  
  minDate: Date = new Date(2020, 0, 1);
  maxDate: Date = new Date(2030, 11, 31);
  minDays: number = 1;      // At least 1 day
  maxDays: number = 90;     // At most 90 days
  
  onRangeChange(args: RangeEventArgs): void {
    this.rangeError = '';
    
    // Validate date range
    if (args.daySpan < this.minDays) {
      this.rangeError = `Range must be at least ${this.minDays} day(s)`;
      return;
    }
    
    if (args.daySpan > this.maxDays) {
      this.rangeError = `Range cannot exceed ${this.maxDays} days`;
      return;
    }
    
    this.startDate = args.startDate;
    this.endDate = args.endDate;
  }
  
  isRangeValid(): boolean {
    return this.rangeError === '';
  }
}
模式 3:响应式表单集成

将 DateRangePicker 集成到响应式表单中:

export class AppComponent implements OnInit {
  reportForm: FormGroup;
  
  constructor(private fb: FormBuilder) {
    this.reportForm = this.fb.group({
      reportName: ['', Validators.required],
      startDate: [new Date(2026, 0, 1), Validators.required],
      endDate: [new Date(), Validators.required]
    });
  }
  
  ngOnInit(): void {
    this.reportForm.get('startDate')?.valueChanges.subscribe(date => {
      console.log('Start date changed:', date);
      this.validateDateRange();
    });
    
    this.reportForm.get('endDate')?.valueChanges.subscribe(date => {
      console.log('End date changed:', date);
      this.validateDateRange();
    });
  }
  
  validateDateRange(): void {
    const start = this.reportForm.get('startDate')?.value;
    const end = this.reportForm.get('endDate')?.value;
    
    if (start && end && start > end) {
      this.reportForm.get('endDate')?.setErrors({ 'invalidRange': true });
    } else {
      this.reportForm.get('endDate')?.setErrors(null);
    }
  }
  
  submitForm(): void {
    if (this.reportForm.valid) {
      console.log('Form values:', this.reportForm.value);
    }
  }
}
<form [formGroup]="reportForm" (ngSubmit)="submitForm()">
  <div>
    <label>Report Name:</label>
    <ejs-textbox 
      formControlName="reportName"
      placeholder="Enter report name">
    </ejs-textbox>
  </div>
  
  <div>
    <label>Report Period:</label>
    <ejs-daterangepicker 
      [formControl]="reportForm.get('startDate')"
      [endDate]="reportForm.get('endDate')?.value">
    </ejs-daterangepicker>
  </div>
  
  <button type="submit" [disabled]="!reportForm.valid">Generate Report</button>
</form>
模式 4:动态范围约束

根据业务逻辑更新范围约束:

export class AppComponent {
  startDate: Date = new Date();
  endDate: Date = new Date();
  
  // Dynamic constraints
  minDate: Date = new Date();
  maxDate: Date = new Date();
  
  reportType: string = 'daily';
  
  onReportTypeChange(type: string): void {
    this.reportType = type;
    this.updateConstraints();
  }
  
  private updateConstraints(): void {
    const today = new Date();
    
    switch (this.reportType) {
      case 'daily':
        // Last 7 days only
        this.minDate = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
        this.maxDate = today;
        break;
      
      case 'monthly':
        // Last 12 months
        this.minDate = new Date(today.getFullYear() - 1, today.getMonth(), 1);
        this.maxDate = today;
        break;
      
      case 'yearly':
        // Last 5 years
        this.minDate = new Date(today.getFullYear() - 5, 0, 1);
        this.maxDate = today;
        break;
    }
  }
}
模式 5:禁用日期范围

禁用特定日期范围(节假日、不可用日期):

export class AppComponent {
  disabledRanges: Array<{start: Date, end: Date}> = [
    { start: new Date(2026, 11, 20), end: new Date(2026, 11, 31) }, // Christmas season
    { start: new Date(2026, 0, 1), end: new Date(2026, 0, 3) }      // New Year
  ];
  
  startDate: Date = new Date();
  endDate: Date = new Date();
  
  onRenderDayCell(args: RenderDayCellEventArgs): void {
    // Disable dates in disabled ranges
    for (const range of this.disabledRanges) {
      if (args.date >= range.start && args.date <= range.end) {
        args.isDisabled = true;
        break;
      }
    }
  }
}
关键属性参考
属性类型描述示例
startDateDate范围的开始日期[startDate]="start"
endDateDate范围的结束日期[endDate]="end"
valueDate[] 或 DateRange选定的日期范围(数组或对象)[(ngModel)]="dateRange"
minDate可选的最早日期[min]="minDate"
maxDate可选的最晚日期[max]="maxDate"
minDaysnumber范围内的最少天数[minDays]="1"
maxDaysnumber范围内的最多天数[maxDays]="90"
formatstring日期显示格式format="dd/MM/yyyy"
separatorstring范围分隔符separator=" to "
placeholderstring占位文本placeholder="Select date range"
presetsPresetsModel[]预定义的范围选项[presets]="presets"
strictModeboolean严格日期验证[strictMode]="true"
readonlyboolean只读输入字段[readonly]="false"
enabledboolean启用/禁用组件[enabled]="true"
localestring区域设置/语言代码locale="en-US"
enableRtlboolean启用 RTL 布局[enableRtl]="false"
cssClassstring自定义 CSS 类cssClass="custom-drp"
widthnumber | string组件宽度width="300px"
allowEditboolean允许手动输入文本[allowEdit]="true"
openOnFocusboolean输入框获得焦点时打开选择器[openOnFocus]="true"
showClearButtonboolean显示清除按钮[showClearButton]="true"
depthCalendarView日历视图深度depth="Month"
常见用例

用例 1:选择报表日期范围

  • 用户为生成报表选择日期范围
  • 应用最小/最大日期限制
  • 支持预设范围(最近 7 天、上个月等)
  • 解决方案:将 startDate/endDate 与预设范围及最小/最大限制结合使用
  • 参考:预设范围 + 日期格式与限制

用例 2:预订系统日期范围

  • 选择预订的入住和退房日期
  • 禁用过去的日期和不可预订日期
  • 显示范围内的天数
  • 解决方案:使用最小日期限制,通过 renderDayCell 渲染禁用日期范围,并计算 daySpan
  • 参考:日期范围选择 + 事件与方法

用例 3:分析日期筛选器

  • 为分析仪表板选择日期范围
  • 提供多个预设选项以便快速选择
  • 提供适配移动设备的响应式界面
  • 解决方案:使用预设范围,并优化响应式样式和触控体验
  • 参考:预设范围 + 样式与自定义

用例 4:无障碍表单字段

  • 在表单中集成 DateRangePicker,并全面支持键盘无障碍操作
  • 兼容屏幕阅读器,符合 WCAG 2.2 标准
  • 解决方案:与 Reactive Forms 配合使用,并设置合适的 ARIA 标签
  • 参考:键盘导航与无障碍

用例 5:国际化日期选择器

  • 支持多种语言和日期格式
  • 支持阿拉伯语、希伯来语的 RTL 布局
  • 使用特定区域设置的格式
  • 解决方案:使用 locale 属性并自定义格式
  • 参考:全球化与本地化

DatetimePicker

本指南全面介绍如何在 Angular 应用中实现 Syncfusion Essential JS 2 DatetimePicker 组件。了解如何创建日期和时间选择界面、管理日历和时间选择器、处理事件并自定义样式。

DatetimePicker 概述

Syncfusion Angular DatetimePicker 组件是一款组合式日期和时间选择控件,提供以下功能:

  • 集成日期与时间选择: 日期使用日历弹出窗口,时间使用时间选择器下拉菜单
  • 灵活的格式设置: 自定义日期格式、时间格式,以及适配区域设置的格式
  • 日历视图: 月(默认)、年和十年视图,并支持流畅导航
  • 时间间隔: 可配置时间选择步长间隔(15、30、60 分钟等)
  • 范围限制: 最小/最大日期和最小/最大时间,并支持严格验证
  • 全面的事件系统: change、focus、blur、open、close、created、destroyed、navigated、renderDayCell 事件
  • 掩码输入支持: 可选的掩码输入格式,便于引导用户输入
  • 持久化与 RTL: 跨重新加载保存状态,并支持从右向左的语言
  • 高级功能: 严格模式验证、浮动标签、键盘自定义、时区支持
  • 无障碍: 全面符合 WCAG 2.2 标准,支持键盘导航和 WAI-ARIA
  • 主题支持: Material、Bootstrap、Tailwind、Fabric,并提供浅色/深色变体
  • 移动设备优化: 在移动设备上使用全屏模式,提供便于触控的界面

程序包: @syncfusion/ej2-angular-datetimepickers

文档导航

根据具体需求阅读以下参考资料:

快速入门

📄 阅读: references/getting-started.md

  • 通过 npm 和 ng add 安装程序包
  • 配置 NgModule 与 Standalone 组件
  • 导入 CSS 主题和依赖项
  • 实现基本的 datetimepicker
  • 初始化组件并运行应用
  • 设置开发服务器
基本实现

📄 阅读: references/basic-implementation.md

  • 使用 ngModel 的简单日期时间选择器
  • 双向数据绑定模式
  • 只读和禁用状态
  • 基本验证和约束
  • 事件处理基础
  • 使用 ViewChild 访问组件
日期和时间配置

📄 阅读: references/date-time-configuration.md

  • 自定义日期格式(format 属性)
  • 配置时间格式(timeFormat 属性)
  • 处理 ISO 日期字符串
  • 日期范围约束(最小/最大日期)
  • 时间范围约束(minTime/maxTime)
  • 解析多种输入格式(inputFormats)
日历和时间视图

📄 阅读: references/calendar-and-time-views.md

  • 日历视图模式(月、年、十年)
  • 用于控制视图的 start 和 depth 属性
  • 时间选择器弹出窗口配置
  • 时间步长间隔和粒度
  • 时间滚动的 ScrollTo 位置
  • “今天”按钮和清除按钮的行为
事件和回调

📄 阅读: references/events-and-callbacks.md

  • 带有 ChangedEventArgs 的 Change 事件
  • 焦点/失焦事件处理
  • 打开/关闭弹出窗口事件
  • 创建/销毁生命周期事件
  • 用于日历导航的 Navigate 事件
  • 使用 RenderDayCell 自定义日期样式
  • 使用清除按钮时触发的 Cleared 事件
方法和命令式访问

📄 阅读: references/methods-and-imperative-access.md

  • ViewChild 访问和组件引用
  • 使用 currentView() 获取当前日历视图
  • 使用 navigateTo() 进行编程式导航
  • 使用 focusIn/focusOut 管理焦点
  • 使用 destroy() 清理并释放资源
  • 使用 getPersistData() 持久化状态
高级功能

📄 阅读: references/advanced-features.md

  • 带有掩码占位符的掩码输入模式
  • 页面重新加载后保留状态
  • RTL(从右到左)语言支持
  • 浮动标签类型和行为
  • 严格模式验证和错误状态
  • 键盘快捷键和按键配置
  • 时区偏移处理
  • 移动设备全屏模式
  • 清除按钮的显示和行为
样式和自定义

📄 阅读: references/styling-and-customization.md

  • CSS 类自定义(cssClass 属性)
  • 主题选择和切换
  • 深色模式实现
  • 组件宽度和 z-index 配置
  • 注入 HTML 属性(htmlAttributes)
  • 日历模式选择(公历或伊斯兰历)
  • 日期标题格式选项
  • 禁用日期和样式状态
无障碍访问和全球化

📄 阅读: references/accessibility-and-globalization.md

  • 符合 WCAG 2.2 和 Section 508 标准
  • WAI-ARIA 属性和角色
  • 键盘导航(方向键、回车、空格、Esc)
  • 屏幕阅读器兼容性和播报
  • 本地化和 locale 属性用法
  • 日期标题格式变化
  • 自定义每周首日
  • 周数和周规则
  • 支持 RTL 文本方向
API 参考

📄 阅读: references/api-reference.md

  • 完整的属性参考,包含类型和默认值
  • 所有方法签名,包含参数和返回类型
  • 所有事件及其事件参数类型
  • 属性说明和使用场景
  • 方法示例和常见模式
  • 类型接口和枚举
  • 用于键盘快捷键的按键配置
  • 全面的逐项属性指南
快速入门示例
// app.component.ts
import { Component } from '@angular/core';
import { ChangedEventArgs } from '@syncfusion/ej2-datetimepickers';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  // Simple datetime value
  dateTimeValue: Date = new Date();
  
  // Configuration
  minDate: Date = new Date(2020, 0, 1);
  maxDate: Date = new Date(2030, 11, 31);
  dateFormat: string = 'dd/MM/yyyy hh:mm a';
  timeFormat: string = 'hh:mm a';
  
  // Event handler
  onDateTimeChange(args: ChangedEventArgs): void {
    console.log('Selected DateTime:', args.value);
    console.log('Event Type:', args.type);
  }
  
  onPopupOpen(): void {
    console.log('Popup opened');
  }
  
  onPopupClose(): void {
    console.log('Popup closed');
  }
}

<div style="padding: 20px;">
  <h2>Select Date & Time</h2>
  
  <ejs-datetimepicker
    id="datetimepicker"
    [value]="dateTimeValue"
    [format]="dateFormat"
    [timeFormat]="timeFormat"
    [min]="minDate"
    [max]="maxDate"
    placeholder="Select date and time"
    (change)="onDateTimeChange($event)"
    (open)="onPopupOpen()"
    (close)="onPopupClose()">
  </ejs-datetimepicker>
  
  <p *ngIf="dateTimeValue">
    Selected: {{ dateTimeValue | date:'medium' }}
  </p>
</div>
常见模式
模式 1:日期时间范围选择

选择预约、预订或活动的开始和结束日期时间:

export class AppComponent {
  startDateTime: Date = new Date();
  endDateTime: Date = new Date(Date.now() + 3600000); // +1 hour
  
  onStartChange(args: ChangedEventArgs): void {
    // Ensure end is after start
    if (this.endDateTime <= args.value) {
      this.endDateTime = new Date((args.value as Date).getTime() + 3600000);
    }
  }
}
模式 2:仅限营业时间

将时间选择限制在营业时间内(上午 9 点至下午 5 点):

export class AppComponent {
  minTime: Date = new Date(2026, 2, 24, 9, 0);  // 9:00 AM
  maxTime: Date = new Date(2026, 2, 24, 17, 0); // 5:00 PM
  
  datetimeValue: Date = new Date(2026, 2, 24, 10, 0);
}
<ejs-datetimepicker
  [value]="datetimeValue"
  [minTime]="minTime"
  [maxTime]="maxTime"
  timeFormat="hh:mm a">
</ejs-datetimepicker>
模式 3:使用掩码输入引导用户输入

使用掩码输入引导用户按照日期时间格式输入:

export class AppComponent {
  datetimeValue: Date;
  maskPlaceholder = {
    day: 'dd',
    month: 'mm',
    year: 'yyyy',
    hour: 'hh',
    minute: 'mm',
    second: 'ss'
  };
}
<ejs-datetimepicker
  [value]="datetimeValue"
  [enableMask]="true"
  [maskPlaceholder]="maskPlaceholder"
  format="dd/MM/yyyy hh:mm:ss">
</ejs-datetimepicker>
模式 4:集成响应式表单

将 datetimepicker 集成到 Angular 响应式表单中:

import { FormBuilder, FormGroup, Validators } from '@angular/forms';

export class AppComponent {
  appointmentForm: FormGroup;
  
  constructor(private fb: FormBuilder) {
    this.appointmentForm = this.fb.group({
      appointmentDateTime: [
        new Date(),
        [Validators.required]
      ]
    });
  }
  
  submitForm(): void {
    if (this.appointmentForm.valid) {
      console.log(this.appointmentForm.value);
    }
  }
}
<form [formGroup]="appointmentForm">
  <ejs-datetimepicker
    formControlName="appointmentDateTime"
    format="dd/MM/yyyy hh:mm a">
  </ejs-datetimepicker>
  
  <button (click)="submitForm()" [disabled]="!appointmentForm.valid">
    Submit
  </button>
</form>
模式 5:禁用日期

禁用周末和指定日期:

export class AppComponent {
  datetimeValue: Date;
  
  onRenderDayCell(args: RenderDayCellEventArgs): void {
    // Disable weekends (0 = Sunday, 6 = Saturday)
    if ((args.date as Date).getDay() === 0 || (args.date as Date).getDay() === 6) {
      args.isDisabled = true;
    }
    
    // Disable specific dates
    const disabledDates = [5, 15, 25]; // 5th, 15th, 25th of each month
    if (disabledDates.includes((args.date as Date).getDate())) {
      args.isDisabled = true;
    }
  }
}
<ejs-datetimepicker
  [value]="datetimeValue"
  (renderDayCell)="onRenderDayCell($event)">
</ejs-datetimepicker>
关键属性参考
属性类型用途
valueDate用于双向绑定的所选日期时间值
formatstring日期显示格式(例如,'dd/MM/yyyy hh:mm a')
timeFormatstring弹出窗口中的时间显示格式(例如,'hh:mm a')
minDate可选择的最早日期
maxDate可选择的最晚日期
minTimeDate可选择的最早时间
maxTimeDate可选择的最晚时间
stepnumber时间间隔(分钟)(15、30、60)
enabledboolean启用/禁用组件
readonlyboolean将输入设为只读(仅可从弹出窗口选择)
placeholderstring输入框中的占位文本
enableMaskboolean启用掩码输入模式
strictModeboolean仅允许有效值
enableRtlboolean支持从右向左书写的语言
enablePersistenceboolean在页面重新加载后保留值
startCalendarView初始日历视图(Month/Year/Decade)
depthCalendarView日历视图的最高层级
localestring格式化所用的区域设置(例如,'en-US'、'de-DE')
常见用例
预约系统
  • 使用日期范围选择,并限制营业时间
  • 根据 min/max time 显示可用时段
  • 使用必填验证器处理表单验证
  • 显示所选日期时间的确认信息
活动安排
  • 选择活动的开始和结束日期时间
  • 使用 renderDayCell 禁用周末
  • 使用 step 设置常用时长间隔(30、60 分钟)
  • 格式化输出以便提交至 API
班次管理
  • 选择班次的开始和结束时间
  • 应用班次时间限制(最早/最晚时间)
  • 处理日期切换(跨午夜的班次)
  • 支持多个时区偏移量
计费与开票
  • 选择发票日期和时间
  • 仅允许选择过去的日期
  • 按用户的区域设置格式显示
  • 使用 ISO 格式导出
后续步骤
  1. 从入门指南开始 → 安装并配置组件
  2. 构建基本实现 → 创建简单的日期时间选择器
  3. 添加事件处理 → 响应用户交互
  4. 实现高级功能 → 添加掩码输入、持久化和 RTL
  5. 自定义外观 → 应用主题和自定义样式
  6. 确保无障碍访问 → 支持键盘和屏幕阅读器
  7. 参考 API → 根据需要查阅完整的 API 文档

TimePicker

这是一份全面的指南,介绍如何在 Angular 应用中实现 Syncfusion Essential JS 2 TimePicker 组件。了解如何创建时间选择界面、管理时间输入、处理事件以及自定义样式。

TimePicker 概述

Syncfusion Angular TimePicker 组件是一款专用的时间选择控件,提供以下功能:

  • 时间选择: 提供可配置时间间隔的弹出列表,供用户选择
  • 灵活格式化: 支持自定义时间格式、骨架选项和基于区域设置的格式化
  • 时间间隔: 支持配置时间选择步长(15、30、60 分钟等)
  • 范围限制: 支持最小/最大时间,并进行严格验证和边界限制
  • 全面的事件系统: change、focus、blur、open、close、created、destroyed、cleared、itemRender 事件
  • 掩码输入支持: 可选的掩码输入格式,引导用户输入
  • 持久化和 RTL: 支持跨重新加载保存状态,以及从右到左语言
  • 高级功能: 严格模式验证、浮动标签、键盘自定义、时区支持
  • 无障碍访问: 完全符合 WCAG 2.2 标准,支持键盘导航和 WAI-ARIA
  • 主题支持: Material、Bootstrap、Tailwind、Fabric,提供浅色/深色变体
  • 针对移动设备优化: 移动设备上的全屏模式,触控友好的界面

包: @syncfusion/ej2-angular-calendars

文档导航

根据具体需求阅读以下参考文档:

开始使用

📄 阅读: references/getting-started.md

  • 通过 npm 和 ng add 安装包
  • NgModule 与 Standalone 组件设置
  • CSS 主题导入和依赖项
  • 基本的 timepicker 实现
  • 组件初始化和运行应用程序
  • 开发服务器设置
基本实现

📄 阅读: references/basic-implementation.md

  • 使用 ngModel 的简单时间选择器
  • 双向数据绑定模式
  • 只读和禁用状态
  • 基本验证和限制
  • 事件处理基础
  • ViewChild 组件访问
时间配置

📄 阅读: references/time-configuration.md

  • 自定义时间格式(format 属性)
  • TimeFormatObject 和骨架选项
  • 步长间隔和时间粒度
  • 最小/最大时间限制
  • 用于时间滚动的 ScrollTo 位置
  • 弹出列表配置
事件和回调

📄 阅读: references/events-and-callbacks.md

  • 搭配 ChangeEventArgs 使用的 Change 事件
  • 焦点/失焦事件处理
  • 打开/关闭弹出框事件
  • created/destroyed 生命周期事件
  • 使用清除按钮时触发的 cleared 事件
  • 用于自定义时间格式的 ItemRender
方法和命令式访问

📄 阅读: references/methods-and-imperative-access.md

  • ViewChild 访问和组件引用
  • 使用 show() 打开时间弹出框
  • 使用 hide() 关闭时间弹出框
  • 使用 focusIn/focusOut 管理焦点
  • 使用 getPersistData() 持久化状态
高级功能

📄 阅读: references/advanced-features.md

  • 带掩码占位符的掩码输入模式
  • 跨页面重新加载保存状态
  • RTL(从右到左)语言支持
  • 浮动标签类型和行为
  • 严格模式验证和错误状态
  • 键盘快捷键和按键配置
  • 时区偏移处理
  • 移动设备的全屏模式
  • 清除按钮的显示和行为
  • OpenOnFocus 弹出框触发方式
样式和自定义

📄 阅读: references/styling-and-customization.md

  • CSS 类自定义(cssClass 属性)
  • 主题选择和切换
  • 深色模式实现
  • 组件宽度和 z-index 配置
  • HTML 属性注入(htmlAttributes)
  • 占位符和启用状态样式
  • 禁用日期的样式和外观
无障碍与全球化

📄 阅读: references/accessibility-and-globalization.md

  • 符合 WCAG 2.2 和 Section 508 标准
  • WAI-ARIA 属性和角色
  • 键盘导航(方向键、回车、空格、退出)
  • 兼容屏幕阅读器并提供播报
  • 本地化和 locale 属性用法
  • 时间格式差异
  • 支持 RTL 文本方向
API 参考

📄 阅读: references/api-reference.md

  • 完整的属性参考,包括类型和默认值
  • 所有方法签名及其参数和返回类型
  • 所有事件及其事件参数类型
  • 属性说明和使用场景
  • 方法示例和常见模式
  • 类型接口和枚举
  • 键盘快捷键的关键配置
  • 全面的逐属性指南
快速入门示例
// app.component.ts
import { Component } from '@angular/core';
import { ChangeEventArgs } from '@syncfusion/ej2-calendars';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  // Simple time value
  timeValue: Date = new Date();
  
  // Configuration
  minTime: Date = new Date(2026, 2, 24, 8, 0);   // 8:00 AM
  maxTime: Date = new Date(2026, 2, 24, 20, 0);  // 8:00 PM
  format: string = 'hh:mm a';
  step: number = 30;  // 30-minute intervals
  
  // Event handler
  onTimeChange(args: ChangeEventArgs): void {
    console.log('Selected Time:', args.value);
    console.log('Selected Text:', args.text);
    console.log('Is User Interaction:', args.isInteracted);
  }
  
  onPopupOpen(): void {
    console.log('Time popup opened');
  }
  
  onPopupClose(): void {
    console.log('Time popup closed');
  }
}

<div style="padding: 20px;">
  <h2>Select a Time</h2>
  
  <ejs-timepicker
    id="timepicker"
    [value]="timeValue"
    [format]="format"
    [min]="minTime"
    [max]="maxTime"
    [step]="step"
    placeholder="Select time"
    (change)="onTimeChange($event)"
    (open)="onPopupOpen()"
    (close)="onPopupClose()">
  </ejs-timepicker>
  
  <p *ngIf="timeValue">
    Selected Time: {{ timeValue | date:'shortTime' }}
  </p>
</div>
常见模式
模式 1:选择营业时间

选择营业时间内的时间(上午 9 点至下午 6 点):

export class AppComponent {
  minTime: Date = new Date(2026, 2, 24, 9, 0);   // 9:00 AM
  maxTime: Date = new Date(2026, 2, 24, 18, 0);  // 6:00 PM
  timeValue: Date = new Date(2026, 2, 24, 10, 0);
  format: string = 'hh:mm a';
  step: number = 15;  // 15-minute intervals
}
<ejs-timepicker
  [value]="timeValue"
  [min]="minTime"
  [max]="maxTime"
  [step]="step"
  [format]="format"
  placeholder="Select appointment time">
</ejs-timepicker>
模式 2:24 小时制

以 24 小时制显示时间:

export class AppComponent {
  timeValue: Date = new Date();
  format: string = 'HH:mm';  // 24-hour format
  step: number = 30;
}
<ejs-timepicker
  [value]="timeValue"
  [format]="format"
  [step]="step"
  placeholder="Select time (24-hour)">
</ejs-timepicker>
模式 3:使用掩码输入引导填写

使用掩码输入引导用户填写时间:

export class AppComponent {
  timeValue: Date;
  enableMask: boolean = true;
  maskPlaceholder = {
    hour: 'hh',
    minute: 'mm',
    second: 'ss'
  };
  format: string = 'hh:mm:ss a';
}
<ejs-timepicker
  [value]="timeValue"
  [enableMask]="enableMask"
  [maskPlaceholder]="maskPlaceholder"
  format="hh:mm:ss a">
</ejs-timepicker>
模式 4:集成响应式表单

将 timepicker 集成到 Angular 响应式表单中:

import { FormBuilder, FormGroup, Validators } from '@angular/forms';

export class AppComponent {
  appointmentForm: FormGroup;
  
  constructor(private fb: FormBuilder) {
    this.appointmentForm = this.fb.group({
      appointmentTime: [
        new Date(),
        [Validators.required]
      ]
    });
  }
  
  submitForm(): void {
    if (this.appointmentForm.valid) {
      console.log(this.appointmentForm.value);
    }
  }
}
<form [formGroup]="appointmentForm">
  <ejs-timepicker
    formControlName="appointmentTime"
    format="hh:mm a"
    placeholder="Select time">
  </ejs-timepicker>
  
  <button (click)="submitForm()" [disabled]="!appointmentForm.valid">
    Submit
  </button>
</form>
模式 5:选择时间范围

选择一段时长的开始和结束时间:

export class AppComponent {
  startTime: Date = new Date();
  endTime: Date = new Date(Date.now() + 3600000);  // +1 hour
  
  onStartTimeChange(args: ChangeEventArgs): void {
    // Ensure end time is after start time
    if (args.value && this.endTime <= args.value) {
      this.endTime = new Date(args.value.getTime() + 3600000);  // +1 hour
    }
  }
}
<div>
  <label>Start Time:</label>
  <ejs-timepicker
    [value]="startTime"
    format="hh:mm a"
    (change)="onStartTimeChange($event)">
  </ejs-timepicker>
  
  <label>End Time:</label>
  <ejs-timepicker
    [value]="endTime"
    [min]="startTime"
    format="hh:mm a">
  </ejs-timepicker>
</div>
关键属性参考
属性类型用途
valueDate用于双向绑定的选定时间值
formatstring时间显示格式(例如,'hh:mm a')
minDate可选时间下限
maxDate可选时间上限
stepnumber时间间隔(分钟)(15、30、60)
enabledboolean启用或禁用组件
readonlyboolean将输入设为只读(仅可从弹出窗口选择)
placeholderstring输入框中的占位文本
enableMaskboolean启用掩码输入模式
strictModeboolean仅允许有效值
enableRtlboolean支持从右向左书写的语言
enablePersistenceboolean在页面重新加载后保留值
scrollToDate时间列表中的默认滚动位置
localestring格式化所用的区域设置(例如,'en-US'、'de-DE')
cssClassstring用于设置样式的自定义 CSS 类
widthstring组件宽度
zIndexnumber弹出窗口的 Z-index
showClearButtonboolean显示或隐藏清除图标
openOnFocusboolean输入框获得焦点时打开弹出窗口
floatLabelTypestring浮动标签行为(Never/Always/Auto)
常见使用场景
预约系统
  • 从列表中选择可用时间段
  • 通过最小/最大时间限制营业时间
  • 使用 15 或 30 分钟的步长间隔
  • 使用必填验证器处理表单验证
  • 显示所选时间的确认信息
排班管理
  • 选择班次的开始和结束时间
  • 应用班次时间限制
  • 支持多个时区偏移量
  • 处理跨午夜的班次转换
  • 以 ISO 格式导出时间
会议安排
  • 在营业时间限制内选择会议时间
  • 使用 30 分钟的步长间隔设置标准时长
  • 按用户的区域设置格式显示时间
  • 通过验证防止重复预订
  • 与日历组件同步以检查可用时间
时间跟踪
  • 记录上班打卡和下班打卡时间
  • 限制在营业时间内
  • 使用掩码输入快速填写
  • 保留时间记录以供审计
  • 导出时间以便与薪资系统集成
活动报名
  • 选择活动参与时间段
  • 显示可用时间范围
  • 使用清除按钮进行更正
  • 支持多种时间格式
  • 为辅助技术提供无障碍支持
后续步骤
  1. 从入门指南开始 → 安装并配置组件
  2. 构建基础实现 → 创建简单的时间选择器
  3. 添加事件处理 → 响应用户交互
  4. 实现高级功能 → 添加带掩码的输入、持久化和 RTL 支持
  5. 自定义外观 → 应用主题和自定义样式
  6. 确保无障碍访问 → 支持键盘和屏幕阅读器
  7. 参考 API → 根据需要查阅完整的 API 文档

评论

支持 Markdown