- UI组件
- 前端
【免费下载链接】ng-zorro-antd
Angular UI Component Library based on Ant Design
ng-zorro-antd 的nz-cron-expression组件提供可视化的 cron 表达式编辑能力。本篇基于官方示例 form(v22.1.0 引入),讲解如何将该组件通过formControlName接入 Angular 响应式表单,如何用cron-parser编写业务级自定义校验器(例如“最小执行间隔 1 天”),并展示错误信息的语义化渲染与底层ControlValueAccessor校验机制,帮助你在定时任务配置类表单中直接落地该组件。
快速开始:用 formControlName 绑定
官方 form 示例 的核心就一行模板代码:
<nz-cron-expression formControlName="cron" />前提是所在组件的模板处于ReactiveFormsModule(或formGroup指令)的管辖范围内,且FormGroup中已声明名为cron的FormControl。组件实现了ControlValueAccessor,会自动与表单控件完成双向同步:
- 表单值(字符串,如
* 1 * * *)写入组件时,组件将其拆分为各时间字段分别渲染到输入框; - 用户修改任意字段时,组件将各字段按固定顺序拼回空格分隔的字符串并通过
onChange回写表单。
完整示例:多规则、多类型的 cron 表单
form.ts 演示了一个完整的定时任务表单,包含普通文本输入、Linux cron、Spring cron 以及带自定义校验器的最小间隔限制四个字段:
<form nz-form nzLayout="vertical" [formGroup]="form" (ngSubmit)="submit()"> <nz-form-item> <nz-form-label [nzSpan]="6">name</nz-form-label> <nz-form-control [nzSpan]="14"> <input nz-input formControlName="username" /> </nz-form-control> </nz-form-item> <nz-form-item> <nz-form-label [nzSpan]="6">nz-cron-linux</nz-form-label> <nz-form-control [nzSpan]="14"> <nz-cron-expression formControlName="cronLinux" /> </nz-form-control> </nz-form-item> <nz-form-item> <nz-form-label [nzSpan]="6">nz-cron-spring</nz-form-label> <nz-form-control [nzSpan]="14"> <nz-cron-expression formControlName="cronSpring" nzType="spring" /> </nz-form-control> </nz-form-item> <nz-form-item> <nz-form-label [nzSpan]="6">minimum interval: 1 day</nz-form-label> <nz-form-control [nzSpan]="14"> <nz-cron-expression formControlName="cronMinInterval" [nzSemantic]="form.controls.cronMinInterval.hasError('minInterval') ? minIntervalError : null" /> <ng-template #minIntervalError> <span class="ant-cron-expression-error">The interval cannot be less than 1 day.</span> </ng-template> </nz-form-control> </nz-form-item> <nz-form-item> <nz-form-control> <button nz-button nzType="primary" [disabled]="!form.valid">submit</button> </nz-form-control> </nz-form-item> </form>对应的组件与表单定义(含自定义校验器):
import { Component, inject } from '@angular/core'; import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, ValidatorFn, Validators } from '@angular/forms'; import { CronExpressionParser } from 'cron-parser'; import { NzButtonModule } from 'ng-zorro-antd/button'; import { NzCronExpressionModule } from 'ng-zorro-antd/cron-expression'; import { NzFormModule } from 'ng-zorro-antd/form'; import { NzInputModule } from 'ng-zorro-antd/input'; const ONE_DAY_IN_MILLISECONDS = 24 * 60 * 60 * 1000; @Component({ selector: 'nz-demo-cron-expression-form', imports: [ReactiveFormsModule, NzButtonModule, NzCronExpressionModule, NzFormModule, NzInputModule], template: `...` // 见上方模板 }) export class NzDemoCronExpressionFormComponent { private readonly fb = inject(FormBuilder); private readonly minIntervalValidator: ValidatorFn = control => { if (typeof control.value !== 'string' || !control.value) { return null; } try { const interval = CronExpressionParser.parse(control.value); const firstExecution = interval.next().toDate(); const secondExecution = interval.next().toDate(); return secondExecution.getTime() - firstExecution.getTime() < ONE_DAY_IN_MILLISECONDS ? { minInterval: true } : null; } catch { return null; // 语法错误交由组件内部校验器标记 } }; readonly form: FormGroup<{ username: FormControl<string | null>; cronLinux: FormControl<string | null>; cronMinInterval: FormControl<string | null>; cronSpring: FormControl<string | null>; }> = this.fb.group({ username: ['cron-expression', [Validators.required]], cronLinux: ['* 1 * * *', [Validators.required]], cronSpring: ['0 * 1 * * *', [Validators.required]], cronMinInterval: ['0 */12 * * *', [Validators.required, this.minIntervalValidator]] }); constructor() { this.form.controls.cronMinInterval.markAsTouched(); } submit(): void { console.log(this.form.value); } }实现要点:
nzType决定字段数:默认linux类型为 5 段(分、时、日、月、周);nzType="spring"时扩展为 6 段(增加秒位)。从 form.ts 可见两个默认值分别为* 1 * * *与0 * 1 * * *,段数正好不同。- 提交按钮受表单有效性控制:
[disabled]="!form.valid",组件内部校验失败(如某段填入非法值)会使FormGroup无效,从而自动禁用提交。 - 构造器中
markAsTouched():初始化即触发校验显示,用户无需先聚焦字段就能看到*/12与“最小间隔 1 天”约束的冲突。 - 自定义校验器与组件内部校验分工:
minIntervalValidator只负责业务规则(两次执行间隔 ≥ 24 小时);表达式本身的语法合法性由组件自带的校验器兜底(详见下文源码解析),因此try/catch中解析失败时返回null,把“格式错误”交由组件标记。
用 nzSemantic 渲染错误信息
示例中第三个字段的[nzSemantic]绑定了一个三元表达式:当cronMinInterval控件携带minInterval错误时,传入#minIntervalError模板;否则传null。
从 cron-expression-preview.component.ts 的模板可以看到nzSemantic的渲染位置:预览区默认显示下一次执行时间(TimeList[0] | date: 'yyyy-MM-dd HH:mm:ss'),一旦提供nzSemantic模板则改为渲染该模板内容。配合样式类ant-cron-expression-error,即可把预览区复用为错误提示区,无需额外的错误文案 DOM。
API 参数说明
以下为 组件文档 中nz-cron-expression的完整参数表:
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|---|---|---|---|---|
[nzType] | cron 规则类型 | 'linux'|'spring' | linux | |
[nzSize] | 设置输入框大小 | 'large'|'small'|'default' | default | |
[nzDisabled] | 禁用 | boolean | false | |
[nzBorderless] | 是否隐藏边框 | boolean | false | |
[nzStatus] | 设置校验状态 | 'error'|'warning' | - | 22.1.0 |
[nzCollapseDisable] | 隐藏折叠面板 | boolean | false | |
[nzExtra] | 自定义渲染右侧的内容 | TemplateRef<void> | - | |
[nzSemantic] | 自定义渲染下次执行时间 | TemplateRef<void> | - |
注意:该组件在文档中标记为experimental: true(见 index.zh-CN.md 的 frontmatter),使用前建议关注版本更新。
支持的 cron 格式
文档给出的字段布局(Spring 类型 6 段):
* * * * * * ┬ ┬ ┬ ┬ ┬ ┬ │ │ │ │ │ | │ │ │ │ │ └ day of week (0 - 7, 1L - 7L) (0 or 7 is Sun) │ │ │ │ └───── month (1 - 12) │ │ │ └────────── day of month (1 - 31, L) │ │ └─────────────── hour (0 - 23) │ └──────────────────── minute (0 - 59) └───────────────────────── second (0 - 59, optional)Linux 类型省略秒位,即 5 段。
源码解析:表单集成的实现机制
阅读 cron-expression.component.ts 可以确认组件如何同时扮演表单控件与校验器两个角色:
1. CVA 与校验器的双注册
组件声明了两个多提供者(cron-expression.component.ts#L110-L121):
providers: [ { provide: NG_VALIDATORS, useExisting: forwardRef(() => NzCronExpressionComponent), multi: true }, { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NzCronExpressionComponent), multi: true } ]这正是formControlName="cron"可以直接生效的原因:NG_VALUE_ACCESSOR让它与FormControl双向绑定,NG_VALIDATORS让它参与表单校验树,校验失败会向上影响form.valid,从而联动示例中的提交按钮禁用逻辑。
2. 值的拆分与回写
writeValue(value)→convertFormat(value)(L190-L203):把表单传入的字符串按空格split,按当前labels顺序映射到内部second/minute/hour/day/month/week六个非空FormControl上,再patchValue渲染;- 内部表单
valueChanges订阅中(L231-L235):每次字段变化都会Object.values(value).join(' ')拼回字符串调用onChange回写外层表单,并刷新预览时间列表。
这里labels由nzType决定(labelsOfType,L49-L54):spring返回 6 段(含second),linux返回 5 段。ngOnChanges中检测nzType变化后会重新计算 labels 并启用/禁用秒位字段(L238-L253),所以动态切换nzType也是安全的。
3. 内置语法校验与对外 validate()
组件内部的cronValidatorFn(L153-L163)把六个字段拼回完整表达式后用CronExpressionParser.parse试解析,抛出异常即返回{ error: true };对外的validate()(L213-L215)则将内部表单的有效性透传给外层表单。这意味着:即便你在FormControl上只挂了Validators.required,非法的 cron 片段同样会使form.valid变为false。
4. 校验状态的计算与继承
组件用三个信号合成最终状态(L176-L185):
private readonly finalStatus = computed(() => this.internalFormStatus() === 'INVALID' ? 'error' : this.inheritedStatus() );internalFormStatus来自内部表单的statusChanges;inheritedStatus优先取父级nz-form-control通过NzFormStatusService下发的状态,否则退回nzStatus输入;- 内部校验失败(INVALID)始终优先呈现为
error,覆盖外部warning等状态。
测试用例 cron-expression.spec.ts 印证了这套行为:
form块中验证了FormControl.disable()会通过setDisabledState传导到组件,为输入组添加ant-input-disabled类,以及父级FormControl的setErrors({ external: true })会反映为ant-input-status-error类;form status块中it.each(['error', 'warning', 'success', 'validating'])验证了nz-form-control的nzValidateStatus能透传到组件;should prioritize internal validation error用例则验证了上文第 4 点的优先级:外部warning状态下人为写入非法的minute值后,最终类名变为ant-input-status-error而非warning。
5. 预览区与“加载更多”
每次值变化后previewDate(L255-L268)调用CronExpressionParser.parse计算未来 5 次执行时间;表达式非法时捕获异常、预览区不显示时间。折叠预览展开后可触发loadMorePreview(L270-L280)继续追加 5 条。预览组件在form.valid为false时(visible输入为 false)显示locale.cronError文案,该文案来自 i18n 服务(组件ngOnInit中通过NzI18nService.getLocaleData('CronExpression')获取,并订阅localeChange实时刷新)。
依赖与引入方式
- 组件文档要求先安装解析库:
npm install cron-parser@^5.5.0;组件库的 package.json 中同样声明了"cron-parser": "^5.5.0"依赖。若你要在业务代码中自写校验器(如上文的minIntervalValidator),建议直接使用该库的CronExpressionParser保持行为一致。 - Angular 包内提供独立的 NzCronExpressionModule,
ng-zorro-antd/cron-expression入口导出该模块、组件与 typings(含Cron、NzCronExpressionType、NzCronExpressionSize等类型)。
小结
将nz-cron-expression接入表单的关键路径是:formControlName完成值绑定(CVA),组件内置的NG_VALIDATORS保证表达式语法合法性,业务方再通过ValidatorFn+cron-parser叠加如最小执行间隔之类的领域规则,并用nzSemantic模板把错误提示就地渲染在预览区。上述机制均可在 cron-expression.component.ts 与 cron-expression.spec.ts 中找到对应实现与测试依据。
- UI组件
- 前端
【免费下载链接】ng-zorro-antd
Angular UI Component Library based on Ant Design
相关推荐
Terragrunt 实战指南:用编排工具管理大规模 Terraform 项目
Terragrunt 实战指南:用编排工具管理大规模 Terraform 项目 Terragrunt 是一款开源的基础设施即代码编排工具,套在 Terrafor
CLIDevOps云原生ng-zorro-antd Cron Expression 组件 nzCollapseDisable 折叠面板隐藏指南
ng zorro antd Cron Expression 组件 nzCollapseDisable 折叠面板隐藏指南 在 ng zorro antd 的 nz
UI组件前端终极指南:如何使用ng-zorro-antd构建动态响应式表单
终极指南:如何使用ng zorro antd构建动态响应式表单 ng zorro antd是基于Ant Design设计规范开发的Angular UI组件库,提
UI组件前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考