Angular 2单个字段多自定义验证器:如何区分验证失败项
嘿,这个问题其实很好解决——你已经离正确答案很近了!核心就在于验证器返回的错误对象的键名,这就是区分不同验证失败的关键。
第一步:修正验证器的返回值
你当前返回的{ myValidator1: false }格式没问题,但更规范的做法是用键名标识验证器,值可以携带具体错误信息(也可以是true)。这样Angular会自动把这个键加入到控件的errors对象中,作为该验证失败的标记。
修改后的第一个验证器:
@Directive({ selector: '[myValidator1]', providers: [{provide: NG_VALIDATORS, useExisting: Validator1, multi: true}] }) export class Validator1 implements Validator { validate(control: AbstractControl): { [key: string]: any; } { if (this.swService.someValidation(control.value) !== -1) { // 用唯一键标识验证器,值可以包含错误细节 return { myValidator1: { message: '该名称已存在,请更换' } }; } return null; } constructor(private swService: StarWarsService, @Attribute('myValidator1') public myValidator1 : string) { } }
第二个验证器同理:
@Directive({ selector: '[myValidator2]', providers: [{provide: NG_VALIDATORS, useExisting: SomeOtherValidation, multi: true}] }) export class SomeOtherValidation implements Validator { validate(control: AbstractControl): { [key: string]: any; } { if (this.swService.validateSomethingDifferent(control.value) !== -1) { return { myValidator2: { message: '名称格式不符合要求' } }; } return null; } constructor(private swService: StarWarsService, @Attribute('myValidator2') public myValidator2 : string) { } }
第二步:在模板中区分验证失败原因
通过控件的errors属性(或更安全的hasError()方法),你可以精准判断是哪个验证器触发了错误,从而显示对应的提示:
<div class="form-group"> <label for="name">Character Name</label> <input type="text" id="name" name="name" ngModel required myValidator1="name" myValidator2="name" #nameCtrl="ngModel"> <!-- 必填项错误提示 --> <span class="help-block" *ngIf="nameCtrl.hasError('required') && nameCtrl.touched"> Please enter a name! </span> <!-- myValidator1失败的提示 --> <small class="text-danger" *ngIf="nameCtrl.hasError('myValidator1') && nameCtrl.touched"> {{ nameCtrl.errors?.myValidator1.message }} </small> <!-- myValidator2失败的提示 --> <small class="text-danger" *ngIf="nameCtrl.hasError('myValidator2') && nameCtrl.touched"> {{ nameCtrl.errors?.myValidator2.message }} </small> </div>
原理说明
Angular的NgModel控件会维护一个errors对象,所有验证失败的验证器返回的键都会作为这个对象的属性存在。比如当myValidator1失败时,nameCtrl.errors.myValidator1就会存在,以此类推。用hasError('键名')方法可以避免直接访问errors时的空指针问题,更稳健。
内容的提问来源于stack exchange,提问作者Martin 膶uka
相关产品推荐
相关产品推荐

