PAYATHON 2026

Angular FormValueControl 如何向外部表单传递验证错误?

数据小陈

结论

FormValueControl.errors 接收外部表单传入的错误状态,供控件显示外部字段的验证错误。控件内部 form() 的错误不会通过它反向传给外部表单。

因此,把 errors 赋给组件后,示例中的 valueForm().errorSummary() 不会自动并入外部字段。FormField 会将绑定字段的状态传给控件,Signal Forms 的验证规则则应定义在表单 schema 中。Angular 的自定义控件指南也分别说明了控件如何显示验证状态,以及 schema 如何执行验证。自定义控件与验证集成 FormValueControl API

将规则封装成可复用 schema

如果希望在控件间复用验证规则,可以像复用控件 schema 一样单独导出规则,再由使用方应用到对应字段。下面以 Test 对象为例:

import { apply, max, schema } from '@angular/forms/signals';

export const testSchema = schema<Test>((path) => {
  max(path.numberValue, 42, { message: 'number must be max 42' });
});

在持有外部表单的组件中,将这个 schema 应用到 Test 对应的路径:

import { form, apply } from '@angular/forms/signals';

model = signal({
  test: {
    booleanValue: false,
    stringValue: 'test',
    numberValue: 42,
  },
});

parentForm = form(this.model, (path) => {
  apply(path.test, testSchema);
});

模板将外部字段绑定到自定义控件:

<custom-generic-form-value-control [formField]="parentForm.test" />

这样,验证规则会针对外部表单中的 test 字段运行。FormField 会把该字段的错误状态传给自定义控件,外部代码也可以从 parentForm.test() 的字段状态中读取错误。官方指南展示了如何通过 schema() 导出可复用规则,并用 apply() 将规则组合进父表单。复用自定义控件的 schema

对当前实现的调整

移除控件内部的 valueForm 验证,以及通过 effect() 将其错误写回 errors 的逻辑。由父表单运行验证规则,控件则通过 errors()、invalid() 等输入信号显示收到的状态。若要在控件中显示错误,可以在模板里读取这些输入:

@for (error of errors(); track $index) {
  <div>{{ error.message }}</div>
}

如果需要保留独立的内部表单,就要自行设计组件输出,再由父组件接收和处理。这些错误不会自动成为 Signal Forms 外部字段的验证错误,也不会自动改变父表单的 valid() 状态。要让父表单据此阻止提交,仍需把相同的验证规则注册到父表单 schema。

备注:内容仅供参考。