如何在不沉默孩子自己的验证器的情况下向角度中的子表单控件添加错误

use*_*582 5 validation angular-validation angular angular-reactive-forms angular-forms

this.form = this.fb.array([
  this.fb.group({ 
    username: [null, Validators.required]
  }),
  this.fb.group({ 
    username: [null, Validators.required]
  }),
  ...
], uniqueUsernameValidator)

const uniqueUsernameValidator = control => {
  // find duplicate
  
  // when flagging the error
  control.get('0.username').setErrors(ifThereIsAnError) // where `ifThereIsAnError` could be null
}
Run Code Online (Sandbox Code Playgroud)

以某种方式uniqueUsernameValidator静默required子表单字段指定的验证。如何解决这个问题呢?

小智 0

为控件创建自定义验证器时,您应该实现ValidatorFn 接口

interface ValidatorFn {
  (control: AbstractControl): ValidationErrors | null
}
Run Code Online (Sandbox Code Playgroud)

实现可能如下所示:

const uniqueUsernameValidator = control => {
  const ifThereIsAnError = /* your logic .. find duplicate */
  
  if(!ifThereIsAnError) {
    return null
  }

  return { unique: true  } 

}
Run Code Online (Sandbox Code Playgroud)

就你而言,我认为你的意思setErrors是不是setError?当使用 AbstractControl 的错误设置器时,您将使用setErrors. 如果您想保留解决方案而不使用 ValidatorFn 则应该在设置新错误之前获取错误:

const uniqueUsernameValidator = control => {
  const errors: ValidationErrors = this.control.errors;
  const keyNameOfYourError = 'unique';

  // reset the last error before revalidating
  if (errors && errors[keyNameOfYourError]) {
    delete errors[keyNameOfYourError];
  }

  // ifThereIsAnError = execute your logic ... find duplicate
  if (ifThereIsAnError) {
    errors[keyNameOfYourError] = true;
    this.control.setErrors(errors);
  }
}
Run Code Online (Sandbox Code Playgroud)

但我建议您使用实现ValidatorFn