在Angular中,如何在创建控件后向FormControl添加验证程序?

在Angular中,如何在创建控件后向FormControl添加验证程序?,angular,forms,angular-reactive-forms,Angular,Forms,Angular Reactive Forms,我们有一个具有动态构建表单的组件。添加带有验证程序的控件的代码可能如下所示: var c = new FormControl('', Validators.required); public exampleForm = new FormGroup({ name: new FormControl('Test name', [Validators.required, Validators.minLength(3)]), email: new FormControl(

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

var c = new FormControl('', Validators.required);
public exampleForm = new FormGroup({
        name: new FormControl('Test name', [Validators.required, Validators.minLength(3)]),
        email: new FormControl('test@example.com', [Validators.required, Validators.maxLength(50)]),
        age: new FormControl(45, [Validators.min(18), Validators.max(65)])
});
但是假设我想在以后添加第二个验证器。我们如何才能做到这一点?我们在网上找不到有关此的任何文档。我确实发现表单控件中有setvalidator

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

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

您只需向FormControl传递一组验证器

下面是一个示例,演示如何向现有FormControl添加验证程序:

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

注意,这将重置您在创建FormControl时添加的所有现有验证器

添加@Delosdos发布的内容

表单组中的控件设置验证程序
this.myForm.controls['controlName'].setValidators([Validators.required])

从FormGroup中的控件中删除验证程序:
this.myForm.controls['controlName'].clearValidators()

运行上述任一行后,更新表单组。
this.myForm.controls['controlName'].updateValueAndValidity()


这是一种以编程方式设置表单验证的神奇方法。

如果您使用的是reactiveFormModule,并且表单组的定义如下:

var c = new FormControl('', Validators.required);
public exampleForm = new FormGroup({
        name: new FormControl('Test name', [Validators.required, Validators.minLength(3)]),
        email: new FormControl('test@example.com', [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返回一个包含所有以前定义的验证器的组合验证器。

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

据我所知,那是不可能的。您唯一能做的就是创建Dynamicly验证程序数组


但是我们缺少的是一个函数addValidator(),它不重写已经添加到formControl的验证器。如果有人对该要求有答案,请张贴在此处。

除了Eduard Void答案之外,这里还有
添加验证程序的方法:

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

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

  this.clearValidators();
  this.setValidators( this.validator ? [ this.validator, ...validators ] : validators );
};
使用它,您可以动态设置验证程序:

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

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

//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保存现有验证程序(非异步验证程序)
我们使用Trimal检查它是否为null并添加到它(这里我们将所需的验证器添加到它),否则,我们只分配我们的新验证器

ha…有时你看东西太久了,最好走开。非常感谢。有没有一种方法可以删除validationany方法可以在不覆盖旧方法的情况下执行此操作?或者有什么方法可以添加新的吗?@danday74,看看这个问题底部Eduard Void的答案。他解释了如何做你需要知道的事情,我也需要知道如何做。在设置了新的验证器之后,我还必须调用表单控件上的
。updateValueAndValidity()
。对我来说,它在没有最后一行的情况下工作,我非常确定Angular的新版本现在可以自己更新表单的有效性。但是谢谢你告诉我们关于
updateValueAndValidity
方法的事情,也许有一天会派上用场的@NinoFiliu
updateValueAndValidity
仍然用于执行验证,在Angular的较新版本中处理方式没有任何不同。发生的情况是
setValidators
更新验证程序,但不运行验证检查,然后使用
updatevalueandvalidation
执行验证。您必须在更改检测为您处理验证程序的位置设置验证程序,但您会发现在组或控件上使用
updateValueAndValidity
,这取决于您刚才设置的验证程序。我在Angular 6上,没有
updateValueAndValidity
,它无法工作。谢谢@shammelburg!在Angular 7上,如果没有最后一行更新,它也不会对我起作用。是的。它在没有
updateValueAndValidity()
的情况下工作,但在某些情况下,它不工作。如果在
setValidators()
之后添加
updateValueAndValidity()
,它将立即影响与控件相关的更改。因此,最好添加updateValueAndValidity()`。这应该是公认的答案。它演示了如何添加像OP requested这样的验证器,还演示了如何保留以前设置的验证器;这是我在谷歌上看到接受答案后的第一件事,因为我不想覆盖我已经拥有的一些验证器,但仍然需要通过编程添加其他验证器。谢谢你的回答,我同意我的前任。问题是如何向控件窗体添加新的验证器,而不是如何替换它。我做了
control.setValidators(control.validator?[control.validator,Validators.email]:Validators.email)
为了避开严格的空检查,您会认为
control.setValidators(control.validator?[control.validator,Validators.email]:Validators.email)将起作用。请参阅@Eduard Void的答案