0Pricing
Angular Academy · 课时

自定义控件中的验证

从自定义控件提供验证器

自定义控件中的验证 是 CoddyKit 上的免费 Angular Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Angular Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Angular Academy 课程共包含 4 节课。

自验证控件

自定义控件可以通过实现 Validator 接口并注册到 NG_VALIDATORS 中来携带自身的验证逻辑,让使用者无需额外配置即可获得有效性验证。

Validator 接口

Validator 要求提供一个 validate 方法。在值有效时,该方法返回 ValidationErrors(错误映射)或 null。

import { Validator, ValidationErrors, AbstractControl } from '@angular/forms';

export class RatingComponent implements Validator {
  validate(control: AbstractControl): ValidationErrors | null {
    return control.value > 0 ? null : { required: true };
  }
}

注册 NG_VALIDATORS

在 NG_VALUE_ACCESSOR 旁边添加第二个多提供程序,用于 NG_VALIDATORS,同样使用 forwardRef。

import { NG_VALIDATORS } from '@angular/forms';

providers: [
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RatingComponent), multi: true },
  { provide: NG_VALIDATORS, useExisting: forwardRef(() => RatingComponent), multi: true }
]

返回错误映射

错误映射中的键会成为 control.errors 中的条目。请使用描述性键和可选的附加数据,以便模板显示有针对性的消息。

validate(control: AbstractControl): ValidationErrors | null {
  const v = control.value;
  if (v == null) return { required: true };
  if (v < this.min) return { min: { required: this.min, actual: v } };
  return null;
}

使用错误信息

模板读取 control.errors 的方式与读取内置验证器错误的方式相同:当控件无效且已接触时显示消息。

<small *ngIf="form.controls.stars.errors?.['required']">Pick a rating</small>

与外部验证器结合

控件中的验证器和使用者在响应式表单中传入的验证器都会运行,并将结果合并。控件的规则会添加到表单规则中,而不是替换它们。

stars: [0, [Validators.required]] // plus the control's own validate()

动态验证

如果验证依赖于会发生变化的输入,请调用已注册的更改回调,通知 Angular 重新运行验证。

private onValidatorChange: () => void = () => {};
registerOnValidatorChange(fn: () => void) { this.onValidatorChange = fn; }

@Input() set min(v: number) { this._min = v; this.onValidatorChange(); }

异步验证

对于服务器检查,请使用 AsyncValidator 实现 validate,使其返回包含错误信息的 Observable 或 Promise,并注册到 NG_ASYNC_VALIDATORS 中。

validate(control: AbstractControl): Observable<ValidationErrors | null> {
  return this.api.isUnique(control.value).pipe(
    map(ok => ok ? null : { taken: true })
  );
}

保持职责单一

只将控件固有的验证逻辑放在控件内部(例如评分必须大于零)。将特定于业务的规则留给使用该控件的表单,以便保持可复用性。

测试验证

直接对 validate 进行单元测试:传入一个带有值的伪造控件,并断言返回的错误映射或 null。

it('requires a rating', () => {
  const c = new FormControl(0);
  expect(component.validate(c)).toEqual({ required: true });
});

完整的自定义控件

值访问器、禁用状态、已接触状态和验证全部实现后,您的组件就成为一个完整且可复用的表单控件;对于使用者来说,它与原生输入控件没有区别。

快速检查

检查您对验证的掌握情况。

回顾

您通过实现 Validator.validate、注册 NG_VALIDATORS、返回错误映射、通过 registerOnValidatorChange 支持动态重新验证,并可选择使用带有 NG_ASYNC_VALIDATORS 的 AsyncValidator,为自定义控件添加了完整的验证支持。

常见问题解答

「自定义控件中的验证」课时是免费的吗?

是的 — 「自定义控件中的验证」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Angular Academy 课程的其余内容,请升级到 CoddyKit PRO。 Angular Academy 课程共包含 4 节课。

「自定义控件中的验证」这节课中我会学到什么?

从自定义控件提供验证器 你通过在浏览器中直接运行的动手代码来练习 Angular Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Angular Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Angular Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「自定义控件中的验证」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Angular Academy 课中编写并运行代码吗?

能。每节 Angular Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. ControlValueAccessor 接口
  2. 编写和注册值
  3. 处理禁用和已触碰状态
  4. 自定义控件中的验证
← 返回 Angular Academy