Form Array all controls 条件要求验证

Form Array all controls conditional required validation

我有表单数组,必须基于变量需要控件,现在我编写了如下自定义验证器

  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 link https://stackblitz.com/edit/angular-form-array-validators?

您正在传递验证器引用,而不是执行和 returning 值。如果您直接使用验证器,那将是正确的方法,但由于您使用的是自定义验证器,验证器将由 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 的内容如何,​​空值总是 return null,所以我评论了出。

StackBlitz

你不能return一个验证器,否则一个对象并创建一个自定义验证器

如果你的变量不随时间变化你可以这样做

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'))

看到,如果在 创建 formControl 之后更改 myVariable 的值,not 工作,验证器得到变量的实际值

如果你需要考虑变量和变量的变化,你需要在创建表单时使用“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>