我使用 ControlValueAccessor 在 Angular 中创建自定义输入。我发现 FormControls 的验证停止工作了。
这是我在 Stackblitz 上制作的一个简单示例。
@Component({
selector: 'app-text-field',
templateUrl: './text-field.component.html',
standalone: true,
imports: [CommonModule, FormsModule],
})
export class TextFieldComponent implements ControlValueAccessor, OnInit {
protected control = inject(NgControl); // control should be injected
onChange(value: string) {}
onTouch() {}
value = '';
ngOnInit(): void {
this.control.valueAccessor = this;
}
registerOnChange(fn: (value: string) => void) {
this.onChange = fn;
}
registerOnTouched(fn: () => void) {
this.onTouch = fn;
}
writeValue(value: string) {
this.value = value;
}
}
我无法提供
NG_VALIDATORS
,因为它会创建循环依赖关系,并且找不到任何在 Angular 16+ 中仍然可用或可以被视为最佳实践的代码。
那么支持验证的最佳方式是什么?
编辑1:
这也是输入的使用方式:
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, ReactiveFormsModule, TextFieldComponent],
template: `
<form [formGroup]="form">
<app-text-field formControlName="a" />
</form>
<p>{{ form.errors }}</p>
`,
})
export class App {
form = new FormGroup({
a: new FormControl<string>('', {
validators: [
Validators.required,
Validators.maxLength(8),
Validators.minLength(2),
],
}),
});
constructor() {
this.form.valueChanges.subscribe((val) =>
console.log(val, this.form.errors)
);
}
}
您可以使用
forwardRef
来打破循环依赖。
@Component({
standalone: true,
imports: [CommonModule, FormsModule, forwardRef(() => NG_VALIDATORS)],
selector: 'app-text-field',
templateUrl: './text-field.component.html',
})
export class TextFieldComponent {}