【问题标题】:Form Array all controls conditional required validation表单数组所有控件条件需要验证
【发布时间】:2021-08-14 13:03:24
【问题描述】:

我有表单数组,必须根据一个变量来控制,现在我编写了如下的自定义验证器

  recurringValidator(): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      if (!control.value) {
        return null;
      }
      if (this.myVariable === 'constant1') {
        return Validators.required;
      }
      return null;
    };
  }

现在这将检​​查 'myVariable' 的值并输入 required 但不知何故它不起作用,我正在添加这个自定义验证器,如下所示

const fbGroup = this.fb.group({
  recurringControl1: this.fb.control('', [this.recurringValidator()]),
  recurringControl2: this.fb.control('', [this.recurringValidator()]),
  recurringControl3: this.fb.control('', [this.recurringValidator()])
});

   this.myForm = this.fb.group({
      control1: fb.control('', [this.recurringValidator()]),
      groupcontrol1: fb.array([])
    });

当我点击提交时,即使 myVariable 的值是 'constant1' ,表单也是有效的。 请有任何建议或修改。

这里是 stackblitz 链接 https://stackblitz.com/edit/angular-form-array-validators?

【问题讨论】:

  • 您从异步验证器函数返回 Validators.requred 的任何特殊原因? @Shaswata
  • 取决于变量值,也可以不要求,

标签: angular typescript angular-forms


【解决方案1】:

您不能返回验证器,否则返回对象并制作自定义验证器

如果你的变量不随时间而改变

recurringValidator(necesary:boolean): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      if (control.value) { //<--if has any value return null
        return null;
      }
      if (necesary) {
        return {required:true} //<--see that you return an object, NOT Validators.required
      }
      return null;
    };
  }

而你使用

control=new FormControl(null,this.recurringValidator(this.myVariable!='constant1'))

看到,如果你改变myVariable的值创建formControl后,不行工作,验证器获取变量的实际值

如果您需要在创建表单时考虑变量和变量更改,请使用“bind(this)”

recurringValidator(): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      if (control.value) {
        return null;
      }
      if (this.myVariable === 'constant1') {
        return {required:true} //<--see that you return an object, NOT Validators.required
      }
      return null;
    };
  }

并使用

control=new FormControl(null,this.recurringValidator().bind(this))

在这种情况下,当您更改变量时,请不要忘记 updateAndValidity 控件,例如

<button (click)="myVariable=!myVariable;
                control.updateValueAndValidity()">
    click
</button>

【讨论】:

    【解决方案2】:

    您正在传递验证器引用,而不是执行并返回值。如果您要直接使用验证器,那将是正确的方法,但由于您使用的是自定义验证器,因此验证器将由 Angular(您的验证器)调用,但对于所需的验证器,您是需要调用它,所以尝试替换:

    recurringValidator(): ValidatorFn {
      return (control: AbstractControl): ValidationErrors | null => {
        if (!control.value) {
          return null;
        }
        if (this.myVariable === 'constant1') {
          return Validators.required;
        }
        return null;
      };
    }
    

    收件人:

    recurringValidator(): ValidatorFn {
      return (control: AbstractControl): ValidationErrors | null => {
        // if (!control.value) {
        //   return null;
        // }
        if (this.myVariable === 'constant1') {
          // Invoking the validator ourselves
          return Validators.required(control);
        }
        return null;
      };
    }
    

    另外,我认为不需要第一个条件!control.value,无论myVariable 的内容如何,​​它都会为空值返回null,所以我注释掉了。

    StackBlitz

    【讨论】:

      猜你喜欢
      • 2011-01-19
      • 2014-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-19
      • 1970-01-01
      • 2018-02-04
      • 1970-01-01
      相关资源
      最近更新 更多