如何在 Angular 响应式表单中执行 required-if?

How to do required-if in Angular Reactive Forms?

我有一个反应式表格,基于 属性 fooRequired 我想将字段设置为必填。

我无法更改它,因为它是初始设置的。那我该怎么办?

fooRequired = false;

form = new FormGroup({
 foo: new FormControl(null, [Validators.required])
});

toggle() { this.fooRequired = !this.fooRequired; }

您需要根据 fooRequired 变量为您的 foo 表单控件使用 setValidator()updateValueAndValidity()。这两个函数将动态更新验证。

演示:https://stackblitz.com/edit/angular-setvalidators-jec7jo?file=src%2Fapp%2Fapp.component.ts

更多阅读: https://www.tektutorialshub.com/angular/how-to-add-validators-dynamically-using-setvalidators-in-angular/

您可以使用自定义函数来负责添加或删除 Validators

export function conditionalValidator(
  predicate: BooleanFn,
  validator: ValidatorFn,
  errorNamespace?: string
): ValidatorFn {
  return formControl => {
    if (!formControl.parent) {
      return null;
    }
    let error = null;
    if (predicate()) {
      error = validator(formControl);
    }
    if (errorNamespace && error) {
      const customError = {};
      customError[errorNamespace] = error;
      error = customError;
    }
    return error;
  };
}

然后你就可以在你的表单控件中使用它了:

this.myForm = this.fb.group({
  myEmailField: [
    "",
    [
      // some normal validatiors
      Validators.maxLength(250),
      Validators.minLength(5),
      Validators.pattern(/.+@.+\..+/),
      // custom validation
      conditionalValidator(
        // depends on fooRequired value
        () => this.fooRequired,
        Validators.required,
        "illuminatiError"
      )
    ]
  ]
});

最后您可以切换 fooRequired 的值并查看结果:

  toggle() {
    this.fooRequired = !this.fooRequired;
    this.myForm.get("myEmailField").updateValueAndValidity();
  }

这里a live demo可以帮助您实现上述答案

以下方法可以解决问题:

toggle() {
  this.fooRequired = !this.fooRequired;
  this.form.controls.foo.setValidators(this.fooRequired ? null : [Validators.required]);
  this.form.controls.foo.updateValueAndValidity();
}

此处,根据 fooRequired 布尔值,设置或删除验证器。最后,更新了新的表单控件设置。