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。
备注:内容仅供参考。
