angular - 在 @Input 变化时触发自定义表单控件验证
我有一个带有一个输入的简单自定义表单控件:
const NGX_HELLO_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => HelloComponent),
multi: true
};
const NGX_HELLO_VALIDATORS = {
provide: NG_VALIDATORS,
useExisting: forwardRef(() => HelloComponent),
multi: true
};
@Component({
selector: 'hello',
template: `<p>Value in custom form control: {{value}}</p>`,
providers: [NGX_HELLO_VALUE_ACCESSOR, NGX_HELLO_VALIDATORS]
})
export class HelloComponent implements OnChanges, ControlValueAccessor, Validator {
@Input() maxLength: number;
value: string;
onChangeCb: (_: any) => void = () => { };
onTouchedCb: () => void = () => { };
ngOnChanges(changes: SimpleChanges): void {
//trigger validation
}
writeValue(value: any): void {
this.value = value;
}
registerOnChange(fn: any): void {
this.onChangeCb = fn;
}
registerOnTouched(fn: any): void {
this.onTouchedCb = fn;
}
validate(control: FormControl): ValidationErrors {
if(this.value && this.value.length > this.maxLength) {
return {
tooLong: this.maxLength
};
}
return null;
}
}
这工作得很好。每当值改变时,Angular 会调用 validate,并且控件会被验证。问题是,当 @Input maxLength 改变时,如何运行验证?
我创建了一个 StackBlitz 示例来尝试操作。
答案#1
ngOnChanges(changes: SimpleChanges): void {
//trigger validation
this.onChangeCb(this.value);
}
行得通,似乎 Angular 在值变化时会重新运行验证。
分叉的 stackblitz
答案#2
对于这种情况,Validator 接口提供了一个通过 registerOnValidatorChange 的回调。
