ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Angular Material Timepicker 组件完全指南:API 结构、表单集成与下拉选项定制

Angular Material Timepicker 组件完全指南:API 结构、表单集成与下拉选项定制 Angular Material Timepicker 组件完全指南API 结构、表单集成与下拉选项定制【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/componentsAngular Material Timepicker 是官方组件库angular/material/timepicker中用于设置日期对象时间部分的组件用户既可以直接在输入框中键入时间也可以从预定义的下拉选项列表中选取。本文以当前仓库的公开 API 报告goldens/material/timepicker/index.api.md为骨架结合官方指南src/material/timepicker/timepicker.md与源码实现timepicker.ts、timepicker-input.ts、util.ts系统讲解 Timepicker 的 API 结构、angular/forms集成、与mat-datepicker组合成日期时间选择器、下拉选项定制、国际化与无障碍配置帮助你直接落地到实际业务表单中。一、组件 API 总览从公开 API 报告认识 Timepickergoldens/material/timepicker/index.api.md是由 API Extractor 自动生成的公开 API 报告它精确刻画了angular/material_timepicker包的对外接口。整包对外导出 3 个组件/指令与 4 个接口、2 个注入令牌导出符号类型作用MatTimepickerD组件selector:mat-timepicker渲染时间下拉面板管理打开/关闭与选项生成MatTimepickerInputD指令selector:input[matTimepicker]时间输入框同时是ControlValueAccessor与ValidatorMatTimepickerToggleD组件selector:mat-timepicker-toggle用于打开面板的时钟按钮MatTimepickerModuleNgModule导出以上三者及CdkScrollableModuleMatTimepickerConfig接口全局默认配置interval、disableRippleMatTimepickerConnectedInputD接口Timepicker 与输入框之间的连接契约MatTimepickerOptionD接口自定义下拉选项结构labelvalueMatTimepickerSelectedD接口选中事件载荷valuesourceMAT_TIMEPICKER_CONFIG注入令牌覆盖全局默认配置MAT_TIMEPICKER_SCROLL_STRATEGY注入令牌自定义面板滚动策略从ɵcmp/ɵdir声明可以确认各成员的信号化输入输出关系例如MatTimepicker的输入有interval、options、disableRipple、aria-label、aria-labelledby、panelClass输出为selected、opened、closedMatTimepickerInput的输入为value、matTimepicker必选、matTimepickerMin、matTimepickerMax、matTimepickerOpenOnClick、disabled输出为valueChange。这些映射与源码中input(...)/model(...)/output()的声明一一对应。1.1MatTimepickerConfig与MAT_TIMEPICKER_CONFIGexport interface MatTimepickerConfig { /** Default interval for all time pickers. */ interval?: string | number; /** Whether ripples inside the timepicker should be disabled by default. */ disableRipple?: boolean; }该令牌定义在 util.tsMatTimepicker与MatTimepickerToggle都会以可选注入的方式读取它inject(MAT_TIMEPICKER_CONFIG, {optional: true})用于初始化interval与disableRipple的默认值。1.2MatTimepickerConnectedInput面板与输入框的桥梁export interface MatTimepickerConnectedInputD { value: SignalD | null; min: SignalD | null; max: SignalD | null; disabled: Signalboolean; focus(): void; getOverlayOrigin(): ElementRefHTMLElement; getLabelId(): string | null; timepickerValueAssigned(value: D | null): void; }MatTimepickerInput实现该接口并在构造时通过registerInput()注册到 Timepicker见 timepicker-input.ts。Timepicker 打开面板时依赖min/max生成选项、依赖getOverlayOrigin()定位浮层、选中后调用timepickerValueAssigned()回写值。二、最小可运行配置连接输入框与开关按钮一个 Timepicker 由文本输入框 下拉面板组成二者通过输入框上的matTimepicker绑定关联mat-timepicker-toggle是可选的开关按钮便于用户一键展开面板。官方最小示例见 timepicker-overview-example.htmlmat-form-field mat-labelPick a time/mat-label input matInput [matTimepicker]picker mat-timepicker-toggle matIconSuffix [for]picker/ mat-timepicker #picker/ /mat-form-fieldmat-timepicker组件本身没有任何可视化内容它只是一个面板逻辑载体最终通过TemplatePortal挂载到由 CDK Overlay 创建的浮层上见 timepicker.ts 的open()流程。mat-timepicker-toggle通过必选输入for对应timepicker输入信号指向 Timepicker 实例。输入框与开关既可以独立使用也可以像上面这样放进mat-form-field此时输入框的getOverlayOrigin()会优先返回表单字段的连接原点见 timepicker-input.ts面板宽度会跟随输入框宽度overlayRef.updateSize({width: input.getOverlayOrigin().nativeElement.offsetWidth})。使用模块时只需引入MatTimepickerModule或 Standalone 模式下直接 importMatTimepicker、MatTimepickerInput、MatTimepickerToggle该模块同时导出CdkScrollableModule以支持面板内滚动见 timepicker-module.ts。三、表单集成Timepicker 是原生的表单控件MatTimepickerInput通过自身提供的NG_VALUE_ACCESSOR、NG_VALIDATORS与MAT_INPUT_VALUE_ACCESSOR三个 provider 接入 Angular 表单体系见 timepicker-input.ts这意味着它可以直接用于formControl、ngModel或响应式表单mat-form-field mat-labelPick a time/mat-label input matInput [formControl]formControl [matTimepicker]picker mat-timepicker-toggle matIconSuffix [for]picker/ mat-timepicker #picker/ /mat-form-field完整示例见 timepicker-forms-example.html。关键行为来自官方指南 Timepicker forms integration 一节用户键入新时间或从下拉中选择时间后该时间会被设置到当前表单控件持有的日期对象上即只修改日期对象的时分秒部分。如果表单控件当前没有值Timepicker 会以今天的日期 所选时间创建一个新日期对象。ControlValueAccessor接口的writeValue在写入时会先经deserialize再getValidDateOrNull清洗避免无效值污染模型见 timepicker-input.ts。当用户输入非法时间后恢复合法输入时组件会用_lastValidDate保存的上一个合法日期并覆盖其时间从而不丢失日期部分见_assignUserSelectiontimepicker-input.ts。3.1 与MatDatepicker组合实现日期 时间选择器Material 的 datepicker 与 timepicker 可以作用于同一个值datepicker 设置整个日期对象timepicker 只修改其中的时间部分二者互补即可组合出完整的 datetime 选择器。官方示例timepicker-datepicker-integration-example.htmlmat-form-field mat-labelMeeting date/mat-label input matInput [matDatepicker]datepicker [(ngModel)]value mat-datepicker #datepicker/ mat-datepicker-toggle [for]datepicker matSuffix/ /mat-form-field mat-form-field mat-labelMeeting time/mat-label input matInput [matTimepicker]timepicker [(ngModel)]value [ngModelOptions]{updateOn: blur} mat-timepicker #timepicker/ mat-timepicker-toggle [for]timepicker matSuffix/ /mat-form-field两个组件共享同一个value绑定。由于 timepicker 内部依赖DateAdapter.sameTime判断值是否变化与 datepicker 共用同一套日期适配器即可保证时间部分的读写一致。示例中为时间输入框设置了updateOn: blur避免键入过程中频繁写值。四、输入校验解析错误与上下界约束官方指南的 Input validation 一节明确了 Timepicker 输入框的两类校验职责时间字符串是否合法、是否落在matTimepickerMin/matTimepickerMax边界内。4.1 解析错误matTimepickerParse当用户键入非法时间字符串如abc、24:67时输入框上报matTimepickerParse错误。字符串由当前日期实现的parseTime方法解析——即底层DateAdapter.parseTime(value, MAT_DATE_FORMATS.parse.timeInput)。以原生适配器为例其TIME_REGEX只接受如下形态见 native-date-adapter.tsH:mm、H:mm:ssH:mm AM/PM、H:mm:ss AM/PM分隔符:或.即也接受22.45这种写法4.2 上下界错误matTimepickerMin/matTimepickerMaxmatTimepickerMin与matTimepickerMax输入别名对应源码中的min/max信号接受带具体时间的日期对象或时间字符串二者同时决定用户可输入的时间边界下拉面板内实际渲染的选项范围。示例官方指南原例input matInput [formControl]formControl [matTimepicker]picker matTimepickerMin12:30 matTimepickerMax17:30设置matTimepickerMin12:30与matTimepickerMax21:25后用户只能在下午 12:30 至晚上 9:25 之间选择越界值会通过值访问器分别上报matTimepickerMin/matTimepickerMax错误。错误对象的结构来自 timepicker-input.ts 的验证器组合matTimepickerParse{text: 用户输入文本}matTimepickerMin{min, actual}actual为反序列化后的当前值matTimepickerMax{max, actual}在模板中可用if配合mat-error展示错误信息完整示例见 timepicker-validation-example.htmlif (formControl.errors?.[matTimepickerParse]) { mat-errorValue isnt a valid time/mat-error } if (formControl.errors?.[matTimepickerMin]) { mat-errorValue is too early/mat-error } if (formControl.errors?.[matTimepickerMax]) { mat-errorValue is too late/mat-error }实现上_updateFormsState()中的 effect 持续计算valueValid、_minValid、_maxValid三个状态任一状态变化即触发_validatorOnChange()见 timepicker-input.ts验证器使用Validators.compose合并三个校验函数。min/max的字符串输入经_transformDateInput调用parseTime转为日期对象解析失败则返回null视为不设界。五、自定义下拉选项interval 与 options默认情况下mat-timepicker下拉面板以30 分钟为间隔生成选项。可通过两种方式定制interval输入或options输入二者互斥。5.1 使用interval输入mat-timepicker interval90m/interval接受字符串或数字合法的间隔写法官方指南完整列举写法含义说明5050 分钟纯数字按分钟解释30m/5h30 分钟 / 5 小时短单位h/H小时m/M分钟s/S秒75 min/1.5 hours75 分钟 / 1.5 小时长单位min/minute/minutes、hour/hours、second/seconds底层解析由 util.ts 的parseInterval完成其匹配正则与换算规则如下const INTERVAL_PATTERN /^(\d*\.?\d)\s*(h|hour|hours|m|min|minute|minutes|s|second|seconds)?$/i;小时单位 × 3600、分钟单位 × 60、其余按秒处理最终统一换算为秒无法匹配或 NaN 时返回null回退到默认 30 分钟。选项的生成逻辑在_generateOptions()timepicker.ts默认间隔为30 * 60秒起始时间为min缺省为当天 00:00:00结束时间为max缺省为当天 23:59:00生成结果会以interval/格式化min/格式化max作为缓存键避免输入未变化时重复计算。generateOptions中还设置了Math.max(interval, 1)的下限防止亚秒间隔导致浏览器卡死见 util.ts。5.2 通过MAT_TIMEPICKER_CONFIG设置全局默认间隔若想让应用内所有 Timepicker 默认使用某个间隔可在providers中提供MAT_TIMEPICKER_CONFIG官方指南原例import {MAT_TIMEPICKER_CONFIG} from angular/material/timepicker; { provide: MAT_TIMEPICKER_CONFIG, useValue: {interval: 90 minutes}, }5.3 使用options输入提供完全自定义的选项当需要更细粒度的控制比如按业务时间段分组时可传入符合MatTimepickerOption接口的数组export interface MatTimepickerOptionD unknown { value: D; // 选项的日期值 label: string; // 展示给用户的文本 }官方示例timepicker-options-example.tscustomOptions: MatTimepickerOptionDate[] [ {label: Morning, value: new Date(2024, 0, 1, 9, 0, 0)}, {label: Noon, value: new Date(2024, 0, 1, 12, 0, 0)}, {label: Evening, value: new Date(2024, 0, 1, 22, 0, 0)}, ];mat-timepicker [options]customOptions #customPicker/对应的 HTML 模板中还演示了interval45min、interval3.5h两种间隔写法见 timepicker-options-example.html。注意options与interval不能同时指定options也不能是空数组——违反这两条规则会在开发模式下直接抛出异常见 timepicker.ts 的 effect 校验。六、自定义开关图标mat-timepicker-toggle默认渲染一个时钟图标。通过matTimepickerToggleIcon属性将自定义元素投影进按钮内部即可替换见 timepicker-toggle.html 的ng-content投影逻辑与官方示例 timepicker-custom-icon-example.htmlmat-timepicker-toggle matIconSuffix [for]picker mat-icon matTimepickerToggleIconkeyboard_arrow_down/mat-icon /mat-timepicker-toggleMatTimepickerToggle其余可用输入来自 API 报告for必选、aria-label、aria-labelledby、disabled、tabIndex、disableRipple。默认 ARIA 标签为 Open timepicker options见 timepicker-toggle.ts。值得注意的实现细节toggle 的点击事件绑定在宿主元素上并在打开面板后调用event.stopPropagation()以避免表单字段自动聚焦到输入框见 timepicker-toggle.ts。七、国际化语言、日期实现与显示格式Timepicker 的国际化与mat-datepicker共享同一套DateAdapter机制由三个要素共同决定日期 localeMAT_DATE_LOCALE日期实现Native / date-fns / Luxon / Moment 适配器显示与解析格式MAT_DATE_FORMATS。7.1 设置 locale默认情况下MAT_DATE_LOCALE使用angular/core的LOCALE_ID。要覆盖它可在启动配置中提供新值bootstrapApplication(MyApp, { providers: [{provide: MAT_DATE_LOCALE, useValue: en-GB}], });也可以在运行时通过DateAdapter.setLocale()动态切换。官方示例即用一个按钮在运行期把 locale 切到保加利亚语timepicker-locale-example.tsthis._adapter.setLocale(bg-BG);注意若使用provideDateFnsAdapterMAT_DATE_LOCALE需要提供该 locale 的数据对象从date-fns/locale导入而非 locale 代码同时还需向MAT_DATE_FORMATS提供与date-fns兼容的配置。7.2 选择日期实现Timepicker 与实现无关implementation-agnostic官方推荐直接使用随包提供的适配器之一适配器函数式 / 模块式日期类型依赖引入位置provideNativeDateAdapter/MatNativeDateModuleDate无angular/material/coreprovideDateFnsAdapter/MatDateFnsModuleDatedate-fnsangular/material-date-fns-adapterng add angular/material-date-fns-adapterprovideLuxonDateAdapter/MatLuxonDateModuleDateTimeLuxonangular/material-luxon-adapterprovideMomentDateAdapter/MatMomentDateModuleMomentMoment.jsangular/material-moment-adapter例如使用 date-fns 适配器import {provideDateFnsAdapter} from angular/material-date-fns-adapter; bootstrapApplication(MyApp, { providers: [provideDateFnsAdapter()] });原生适配器的时间解析限制provideNativeDateAdapter通过正则实现时间解析只支持 AM/PM 时间如1:45 PM或 24 小时制时间如22:45、22.45无法适配格式不同的 locale。若 locale 格式特殊建议换用上述其他适配器或通过继承DateAdapter类angular/material/core自行实现。7.3 自定义解析与显示格式MAT_DATE_FORMATSTimepicker 使用MAT_DATE_FORMATS对象解析与显示日期对象其格式最终透传给DateAdapter因此提供的格式必须与所选适配器兼容。MAT_DATE_FORMATS与mat-datepicker共用同一个令牌——如果应用已在用 datepicker通常已配置好但timepicker 额外要求以下三个字段必须存在display.timeInputdisplay.timeOptionLabelparse.timeInput以内置的MAT_NATIVE_DATE_FORMATS为例native-date-formats.tsexport const MAT_NATIVE_DATE_FORMATS: MatDateFormats { parse: { dateInput: null, timeInput: null, // 解析时间输入 }, display: { dateInput: {year: numeric, month: numeric, day: numeric}, timeInput: {hour: numeric, minute: numeric}, // 输入框显示格式 monthYearLabel: {year: numeric, month: short}, dateA11yLabel: {year: numeric, month: long, day: numeric}, monthYearA11yLabel: {year: numeric, month: long}, timeOptionLabel: {hour: numeric, minute: numeric}, // 下拉选项显示格式 }, };validateAdapterutil.ts会在组件构造时校验适配器与格式缺少DateAdapter/MAT_DATE_FORMATS提供者、或上述三个 time 格式字段缺失时会抛出下文疑难解答中对应的错误。如果想使用官方适配器但换成自己的格式有两种方式把格式对象传给 providers 函数或自行提供MAT_DATE_FORMATS令牌bootstrapApplication(MyApp, { providers: [provideNativeDateAdapter(MY_NATIVE_DATE_FORMATS)], });八、无障碍AccessibilityTimepicker 实现了 ARIA combobox 交互模式其 ARIA 角色分配如下输入框rolecombobox、aria-haspopuplistbox并根据面板状态动态维护aria-expanded、aria-controls、aria-activedescendant见 timepicker-input.ts 的宿主绑定与_ariaActiveDescendant/_ariaExpanded/_ariaControls三个 computed 信号面板容器rolelistbox见 timepicker.html面板内每个选项roleoption由mat-option提供。默认情况下listbox 通过所在mat-form-field的标签来标注_getAriaLabelledby()会回退到ariaLabelledby或输入框的getLabelId()见 timepicker.ts。如果不使用表单字段或想自定义标签可通过mat-timepicker的ariaLabel/ariaLabelledby输入设置。键盘交互方面面板打开后由ActiveDescendantKeyManager驱动方向键导航支持 Home/End、PageUp/PageDown、纵向方向键见 timepicker.tsEnter选中当前项、Escape关闭、Tab关闭面板且在关闭时调用scrollOptionIntoView保证活动项可见_handleKeydowntimepicker.ts。九、疑难解答Troubleshooting官方指南总结了 5 类常见错误及解决方案以下全部可在源码中找到对应的抛错点MatTimepicker: No provider found for DateAdapter/MAT_DATE_FORMATS未提供 Timepicker 工作所需的注入项。解决在应用配置中加入provideNativeDateAdapter()或provideMomentDateAdapter()等适配器见 util.ts 的missingAdapterError。MatTimepicker: Incomplete MAT_DATE_FORMATS has been provided提供的MAT_DATE_FORMATS缺少display.timeInput、display.timeOptionLabel或parse.timeInput字段。解决按上文 7.3 节补齐这三个字段见 util.ts。Cannot specify both the options and interval inputs at the same timeoptions与interval互斥模板中需移除其中一个见 timepicker.ts。Value of options input cannot be an empty arrayoptions不能为空数组否则用户无任何可选项见 timepicker.ts。A MatTimepicker can only be associated with a single input同一个mat-timepicker只允许一个input通过matTimepicker属性关联当第二个输入框试图注册时抛出见 timepicker.ts 的registerInput。十、深入源码面板的生命周期与值回写最后从源码层面对照 API 报告理解几个关键机制的实现均为可验证的实现事实打开流程open()先聚焦输入框随后_generateOptions()按当前interval/options与min/max生成选项再通过 CDK Overlay 创建浮层createFlexibleConnectedPositionStrategy首选输入框下方对齐、次选上方对齐并附加mat-timepicker-above类使用TemplatePortal挂载面板模板并注册detachments、keydownEvents、outsidePointerEvents三个订阅timepicker.ts。选中回写_selectValue(option)先关闭面板、同步选中态然后先调用_input().timepickerValueAssigned(option.value)让输入框更新表单控件再发射selected事件timepicker.ts输入框侧timepickerValueAssigned比较sameTime后经_assignUserSelection走_onChange传播给表单并更新valuemodeltimepicker-input.ts。键盘直达输入框聚焦时按上/下方向键会直接open()_handleKeydowntimepicker-input.tsEscape可清空当前值。locale 联动DateAdapter.localeChanges被订阅后若面板处于打开状态会重新生成选项、输入框在失焦状态下会重新格式化显示值保证语言切换即时生效timepicker.ts。滚动策略MAT_TIMEPICKER_SCROLL_STRATEGY默认提供createRepositionScrollStrategytimepicker.ts面板打开期间页面滚动时会跟随输入框重定位。结语本文以公开 API 报告 goldens/material/timepicker/index.api.md 为主线完整覆盖了MatTimepicker、MatTimepickerInput、MatTimepickerToggle三个构件及MAT_TIMEPICKER_CONFIG、MAT_TIMEPICKER_SCROLL_STRATEGY两个令牌的用法并延伸到表单集成、日期选择器组合、校验、选项定制、国际化与无障碍。实战中只需记住三件事用matTimepicker绑定输入框、按需提供日期适配器provideNativeDateAdapter起步、用interval/options控制面板选项即可在表单中快速交付专业的时间选择体验。【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/components创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表