为什么自定义组件中 validate 直接被调用
来源:4-7 响应式表单处理和自定义表单控件(下)

_Minos
2019-06-11
麻烦老师看一下 下面加粗的字体, 我的疑问是 在ImageListSelectComponent 组件中,自定义了校验器,但是他怎么就生效了呢?正常的校验器不是应该在 FormControl 创建的时候加的吗
import { Component, OnInit, Input, forwardRef } from ‘@angular/core’;
import { ControlValueAccessor ,NG_VALUE_ACCESSOR, NG_VALIDATORS, FormControl } from ‘@angular/forms’;
@Component({
selector: ‘app-image-list-select’,
templateUrl: ‘./image-list-select.component.html’,
styleUrls: [’./image-list-select.component.scss’],
providers: [
{
provide : NG_VALUE_ACCESSOR,
useExisting: forwardRef(()=>ImageListSelectComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(()=> ImageListSelectComponent),
multi: true
}
]
})
export class ImageListSelectComponent implements ControlValueAccessor {
@Input() title = ‘请选择头像’;
@Input() cols= 6;
@Input() rowHeight = ‘64px’;
@Input() items: string[] = [];
@Input() useSvgIcon = false;
@Input() itemWidth = ‘80px’;
selected: string= ‘’;
private propagateChange = (_: any)=>{};
constructor() { }
writeValue(obj: any):void {
this.selected = obj;
}
registerOnChange(fn: any):void {
this.propagateChange = fn;
}
registerOnTouched(fn: any):void {}
onChange(i, ev: Event) {
console.log(i);
this.selected = this.items[i];
this.propagateChange(this.selected);
}
validate(c: FormControl): {[key: string]: any} { return this.selected? null : { imageListInvalid: { valid : false } };
}
}
1回答
-
我们有两种方式声明一个 Validator,一种是在组件类中
const formCt = new FormControl('', Validators.required);
另一种是在模版中
<input [formControl]='formCtrl' required>
第二种方式其实是通过 `NG_VALIDATORS` 这个 Token 来实现的,而上面这个 `required` 其实是一个指令,其实现方式类似下面这种(仅仅是示例,不是 ng 源码)。而你如果记得我说过组件其实也是一种指令,只不过是带模板的指令,你就能知道为什么我们写一个表单组件,他自己就可以验证了
@Directive({ selector: '[required]', providers: [{ provide: NG_VALIDATORS, useExisting: RequiredValidatorDirective, multi: true }] }) class RequiredValidatorDirective implements Validator { validate(control: AbstractControl): ValidationErrors | null { return { 'custom': true }; } }
012019-06-12
Angular打造企业级协作平台,让你在Angular领域中出类拔萃
998 学习 · 536 问题
相似问题