Angular中,控件创建后如何给FormControl添加Validator?

问题描述 投票:0回答:8

我们有一个具有动态构建形式的组件。添加带有验证器的控件的代码可能如下所示:

var c = new FormControl('', Validators.required);

但是假设我想添加第二个验证器later。我们怎样才能做到这一点?我们在网上找不到任何文档。我确实发现虽然在表单控件中有

setValidators

this.form.controls["firstName"].setValidators 

但不清楚如何添加新的或自定义的验证器。

angular forms angular-reactive-forms
8个回答
181
投票

您只需传递

FormControl
一组验证器。

这里是一个示例,展示了如何将验证器添加到现有的 FormControl:

this.form.controls["firstName"].setValidators([Validators.minLength(1), Validators.maxLength(30)]);

注意,这将重置您在创建

FormControl
.

时添加的任何现有验证器

Angular 12 更新

从 Angular 12 开始,如果你想在不删除现有验证器的情况下向表单添加新的验证器,你可以使用

addValidator
:

this.form.controls["firstName"].addValidators([Validators.minLength(1), Validators.maxLength(30)]);

134
投票

添加@Delosdos 发布的内容。

FormGroup

中的控件设置
验证器:
this.myForm.controls['controlName'].setValidators([Validators.required])

从 FormGroup 的控件中移除 验证器:

this.myForm.controls['controlName'].clearValidators()

Update FormGroup 一旦你运行了以上任何一行。

this.myForm.controls['controlName'].updateValueAndValidity()

这是一种以编程方式设置表单验证的绝佳方式。


117
投票

如果您使用的是 reactiveFormModule 并且 formGroup 定义如下:

public exampleForm = new FormGroup({
        name: new FormControl('Test name', [Validators.required, Validators.minLength(3)]),
        email: new FormControl('[email protected]', [Validators.required, Validators.maxLength(50)]),
        age: new FormControl(45, [Validators.min(18), Validators.max(65)])
});

比您能够使用这种方法向 FormControl 添加一个新的验证器(并保留旧的):

this.exampleForm.get('age').setValidators([
        Validators.pattern('^[0-9]*$'),
        this.exampleForm.get('age').validator
]);
this.exampleForm.get('email').setValidators([
        Validators.email,
        this.exampleForm.get('email').validator
]);

FormControl.validator 返回一个包含所有先前定义的验证器的组合验证器。


6
投票

如果您需要删除添加的表单控件上的一些现有验证,请在控件上调用以下函数

this.form.controls["name"].clearValidators();

之后你需要调用下面的函数来更新表单控件,它会立即在表单控件上生效。

this.form.controls['name'].updateValueAndValidity();

如果您需要在已添加的表单控件上添加一些验证,请在控件上调用以下函数

this.signupForm.controls['name'].setValidators([Validators.required]);

之后立即调用

updateValueAndValidity()
函数,所以它会立即反映出来。


6
投票

除了 Eduard Void 之外,这里还有

addValidators
方法:

declare module '@angular/forms' {
  interface FormControl {
    addValidators(validators: ValidatorFn[]): void;
  }
}

FormControl.prototype.addValidators = function(this: FormControl, validators: ValidatorFn[]) {
  if (!validators || !validators.length) {
    return;
  }

  const old_validator = this.validator;

  this.clearValidators();
  this.setValidators( old_validator ? [ old_validator , ...validators ] : validators );
};

使用它你可以动态设置验证器:

some_form_control.addValidators([ first_validator, second_validator ]);
some_form_control.addValidators([ third_validator ]);

5
投票

我认为选择的答案不正确,因为原始问题是“如何在创建 formControl 后添加新的验证器”。

据我所知,这是不可能的。你唯一能做的就是动态创建验证器数组。

但是我们想念的是函数 addValidator() 不会覆盖已经添加到 formControl 的验证器。如果有人对此要求有答案,很高兴张贴在这里。


0
投票

一个简单的解决方案是首先获取表单控件中的所有验证器,并在需要的代码将像这样时为其分配一个新的 validatorFn。

//get existing validators and assign a new validator

const formControl = this.form.controls["firstName"];

 const validators: ValidatorFn[] = !!formControl.validator ?
  [formControl.validator, Validators.required] :
  [Validators.required];

formControl.setValidators(validators);

formControl.validtor 持有现有的验证器(不是 asyncValidators) 我们使用三元检查它是否不为空并添加到它(这里我们向它添加所需的验证器),否则,我们只是分配我们的新验证器


0
投票

根据其他表单控件的值更新验证器。

首先设置表格:

  form: FormGroup = new FormGroup({
    firstName: new FormControl<string>(null),
    lastName: new FormControl<string>(null),
  });

然后在初始化:

  ngOnInit(): void {
    this.form.get('firstName').valueChanges.subscribe((value) => {
      if (value) {
        this.form.get('lastName').setValidators(Validators.nullValidator);
      } else {
        this.form.get('lastName').setValidators(Validators.required);
      }
      this.form.get('lastName').updateValueAndValidity({ emitEvent: false });
    });
    this.form.get('lastName').valueChanges.subscribe((value) => {
      if (value) {
        this.form.get('firstName').setValidators(Validators.nullValidator);
      } else {
        this.form.get('firstName').setValidators(Validators.required);
      }
      this.form.get('firstName').updateValueAndValidity({ emitEvent: false });
    });
  }

添加

{ emitEvent: false }
很重要,这样您就不会得到超出最大调用堆栈大小错误

© www.soinside.com 2019 - 2024. All rights reserved.