为什么自定义组件中 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回答

接灰的电子产品

2019-06-11

我们有两种方式声明一个 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 };
  }
}


0
1
_Minos
非常感谢!
2019-06-12
共1条回复

Angular打造企业级协作平台,让你在Angular领域中出类拔萃

全网首个介绍官方 Material 组件库用法与 Redux 在 Angular 中的应用

998 学习 · 536 问题

查看课程