【问题标题】:Conditional required validation in angular reactive form角度反应形式的条件要求验证
【发布时间】:2019-03-22 18:58:09
【问题描述】:

我想根据其他表单值对某些属性应用条件验证。我已经提到了一些答案Angular2: Conditional required validation,但这些都不能满足我的需要。因为我必须在我的大型企业应用程序的 40 多个表单(大约 30 个字段)中实现条件验证。我不想在每个组件中编写相同的代码并更改 FormControl 名称。我不知道如何通过指令来实现。

如果年龄控制值 v 大于 18,则需要许可证号字段。

这是我的代码:

this.userCustomForm = this.angularFormBuilder.group({
age:['',Validators.required],
licenseNo:[''] // Here I want to apply conditional required validation.
});

在我的应用程序中,在某些情况下,我希望根据嵌套的 FormGroupFormArray 值设置条件验证。

请指导我,我怎样才能做到这一点。

【问题讨论】:

  • 也许this approach 可以工作?
  • 我想根据年龄值对我的 licenseNo 字段应用有条件的必需验证。

标签: angular


【解决方案1】:

我的建议是使用动态验证。

订阅 userCustomForm 的年龄字段的更改,当年龄达到需要验证许可证的条件时,使用 setValidators() 动态添加 validators.required 并在必要时使用 clearValidators() 动态清除验证器。

    this.userCustomForm.get('age').valueChanges.subscribe(val => {
        if (condition) { // for setting validations
          this.userCustomForm.get('licenseNo').setValidators(Validators.required);
        } 
        if (condition) { // for clearing validations
          this.userCustomForm.get('licenseNo').clearValidators();
        }
        this.userCustomForm.get('licenseNo').updateValueAndValidity();
    });

【讨论】:

  • 我相信您还需要致电updateValueAndValidity 在上述情况下,它将是this.userCustomForm.get('licenseNo').updateValueAndValidity();
【解决方案2】:

对我来说它完美地工作如下:

this.userCustomForm.get('age').valueChanges.subscribe(val => {
  if (condition) {
    this.userCustomForm.controls['licenseNo'].setValidators([Validators.required]);
  } else {
    this.userCustomForm.controls['licenseNo'].clearValidators();
  }
  this.userCustomForm.controls['licenseNo'].updateValueAndValidity();
});

您必须 updateValueAndValidity 表单才能使更改生效。

希望这会有所帮助!

【讨论】:

  • 我们可以把 updateValueAndValidity() 放在 if else 语句的外面,不用重复了。
  • 嗨!这段代码会在 ngOnInit() 方法中吗?
【解决方案3】:

有一种更通用的方法可以用于多种目的,而不仅仅是这个。

每次您想有条件地将 Validators.required 添加到控件时,您都可以使用此函数。

首先创建这个函数(在服务中应该是最好的主意,因为它是通用的,所以你可以稍后在不同的组件中以不同的条件使用它,但对于示例它在同一个组件中)

import { FormGroup, Validators } from '@angular/forms';

conditionallyRequiredValidator(masterControlLabel: string, operator: string, conditionalValue: any, slaveControlLabel: string) {
  return (group: FormGroup): {[key: string]: any} => {
    const masterControl = group.controls[masterControlLabel];
    const slaveControl = group.controls[slaveControlLabel];     
    if (eval(`'${masterControl.value}' ${operator} '${conditionalValue}'`)) { 
      return Validators.required(slaveControl)
    }
    slaveControl.setErrors(null); 
    return null;
  }
}

ma​​sterControlLabel:将有条件地将 Validators.required 添加到 slaveControl

的控件

operator:您想用来比较 masterControl 值与 conditionalValue

的运算符

conditionalValue:您希望 masterControl 值必须匹配的值才能有条件地将验证器添加到 slaveControl

slaveControlLabel:将接收(或不接收)条件 Validators.required

的控件

第二个也是最后一个,像这样在你的 formGroup 中添加验证器参数(或验证器参数,如果需要进行多重验证):

import { FormBuilder, FormGroup, Validators } from "@angular/forms";

constructor(
  private angularFormBuilder: FormBuilder,
){ }

myFormGroup: FormGroup = this.angularFormBuilder.group({
  age: ['', Validators.required],
  licenceNo: [''],
}, {validator: conditionallyRequiredValidator('age', '>=', 18, 'licenceNo')});

在此示例中,如果年龄严格超过或等于 18 岁,则 licenceNo 控件将有条件地要求

【讨论】:

    【解决方案4】:

    我通过这样做解决了这个问题:

    this.userCustomForm = new FormGroup({
        age: new FormControl('',Validators.required)
        licenseNo: new FormControl('', condition ? Validators.required : [])
    });
    

    还有另一种方法可以使用setValidatorsclearValidators 方法,请参阅以下示例:

    if(condition) {
        this.userCustomForm.get('licenseNo').setValidators(Validators.required);
    } else {
        this.userCustomForm.get('licenseNo').clearValidators();
    }
    

    【讨论】:

      【解决方案5】:

      通过FormControl类的setValidators方法有条件地设置验证器,即

      this.userCustomForm = this.angularFormBuilder.group({
          age:['', Validators.required],
          licenseNo:['']
      });
      
      if (condition) {
          this.userCustomForm.get('licenseNo').setValidators([
              Validators.required
          ]);
      }
      

      【讨论】:

        猜你喜欢
        • 2020-10-26
        • 2020-01-27
        • 2021-07-19
        • 2020-10-27
        • 1970-01-01
        • 1970-01-01
        • 2022-11-25
        • 1970-01-01
        • 2022-11-03
        相关资源
        最近更新 更多