You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:41:42