Angular - 动态添加/删除验证器

时间:2018-03-02 18:13:42

标签: angular angular-forms angular-validation

我的FormGroup定义如下:

this.businessFormGroup: this.fb.group({
    'businessType': ['', Validators.required],
    'description': ['', Validators.compose([Validators.required, Validators.maxLength(200)])],
    'income': ['']
  })

现在businessTypeOther时,我想从Validators.required中移除description验证程序。如果businessType不是Other,我想添加回Validators.required

我使用以下代码动态添加/删除Validators.required。但是,它会清除现有的Validators.maxLength验证程序。

if(this.businessFormGroup.get('businessType').value !== 'Other'){
    this.businessFormGroup.get('description').validator = <any>Validators.compose([Validators.required]);               
} else {                
    this.businessFormGroup.get('description').clearValidators();               
}

this.businessFormGroup.get('description').updateValueAndValidity(); 

我的问题是,在添加/删除required验证程序时,如何保留现有验证程序。

7 个答案:

答案 0 :(得分:15)

Angular表单具有内置函数setValidators(),可以对Validators进行编程分配。

您可以这样做:

if(this.businessFormGroup.get('businessType').value !== 'Other'){
    this.businessFormGroup.controls['description'].setValidators([Validators.required, Validators.maxLength(200)]);              
} else {                
    this.businessFormGroup.controls['description'].setValidators([Validators.maxLength(200)]);               
}

请务必记住,使用此方法会覆盖现有的验证程序,因此您需要包含您正在重置的控件所需的所有验证程序。< / p>

答案 1 :(得分:5)

如果多次更改“要求验证者”(例如,使用复选框),则应添加以下内容:

this.formGroup.controls["firstName"].setErrors(null);

所以:

  onAddValidationClick(){
         this.formGroup.controls["firstName"].setValidators(Validators.required);
        this.formGroup.controls["firstName"].updateValueAndValidity();
      }

onRemoveValidationClick(){
         this.formGroup.controls["firstName"].setErrors(null);
         this.formGroup.controls["firstName"].clearValidators();
        this.formGroup.controls["firstName"].updateValueAndValidity();
      }

答案 2 :(得分:3)

天真的方法是在条件变量发生变化时设置控件的验证器。但是通过使用一些间接+函数式编程,我们实际上可以做得更好。

考虑是否存在descriptionIsRequired吸气剂,它起到了一个boolan旗帜的作用。

思路:

  • 创建一个自定义验证器函数,该函数将descriptionIsRequired作为参数,并根据它验证对所需的+ maxLength或maxLength的控件。
  • 以这种方式将自定义验证器绑定到描述控件,当评估控件的有效性时,应考虑descriptionIsRequired的最新值。

第一点很容易实现:

function descriptionValidator(required: boolean): ValidatorFn {
  return (formControl: FormControl): ValidationErrors => {
    if (required) {
      return Validators.compose([Validators.required, Validators.maxLength(200)])(formControl);
    } else {
      return Validators.maxLength(200)(formControl);
    }
  }
}

请注意,这是一个自我封装的功能。

第二点有点棘手,但最后它看起来像这样:

export class FooComponent {
  constructor(){
    this.form = fb.group({
      description: ['initial name', this.validator()]
    });
  }

  private get descriptionIsRequired(): boolean {
   ...
  }

  private validator(): ValidatorFn {
    return (c: FormControl): ValidationErrors => descriptionValidator(this.descriptionIsRequired)(c);
  }
}

对正在发生的事情的一个小解释:

  • validator方法返回一个函数
  • validator返回的函数可以被视为工厂方法:无论何时调用它,都会返回一个新函数,更具体地说,是descriptionValidator的新实例。最新descriptionIsRequired值。

以下stackblitz

中的实时演示

答案 3 :(得分:2)

也许这会有所帮助:

将Validators.required添加到现有AbstractControl

的validatorset
if (c.validator !== null) {
        c.setValidators([c.validator, Validators.required])
  } else {
        c.setValidators([Validators.required])
  }

答案 4 :(得分:0)

这是我的工作

   onAddValidationClick(){
         this.formGroup.controls["firstName"].setValidators(Validators.required);
        this.formGroup.controls["firstName"].updateValueAndValidity();
      }

onRemoveValidationClick(){
         this.formGroup.controls["firstName"].clearValidators();
        this.formGroup.controls["firstName"].updateValueAndValidity();
      }

答案 5 :(得分:0)

任何仍在寻找答案的人,都可以这样做,可以在ngOnInit()或任何您喜欢的地方进行处理。

   const validators = formGroup.validator; /* or control.validator */

   const newValidator = CustomValidator.checkUserNameValidity(); 

   /* Add to existing validator */

   if(validator) {
      formGroup.setValidators([validators, newValidator])
   } else {. /* if no validators added already */
      formGroup.setValidators([newValidator]);
   }

也对asyncValidator进行同样的操作。

答案 6 :(得分:0)

如果多次更改“要求验证者”(例如,使用复选框),则应添加以下内容: 非常重要的领域! this.formGroup.controls [“ firstName”]。setErrors(null);