En Angular, ¿cómo agregar Validator a FormControl después de que se crea el control?

84

Tenemos un componente que tiene una forma construida dinámicamente. El código para agregar un control con validadores podría verse así:

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

Pero digamos que quiero agregar 2nd Validator más tarde . ¿Cómo podemos lograr esto? No podemos encontrar ninguna documentación sobre esto en línea. Encontré aunque en los controles de formulario hay setValidators

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

pero no está claro cómo agregar un validador nuevo o personalizado.

melegante
fuente

Respuestas:

109

Simplemente pasa al FormControl una matriz de validadores.

Aquí hay un ejemplo que muestra cómo puede agregar validadores a un FormControl existente:

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

Tenga en cuenta que esto restablecerá los validadores existentes que agregó cuando creó FormControl.

Andy-Delosdos
fuente
5
ja ... a veces miras algo durante tanto tiempo que es mejor simplemente alejarte. ¡¡GRACIAS!!
melegant
1
¿Hay alguna manera de eliminar la validación
Abhijith ss
7
alguna forma de hacer esto sin anular los antiguos? o alguna forma de agregar los nuevos?
danday74
1
@ danday74, consulte la respuesta de Eduard Void al final de esta pregunta. Debería aceptarse la respuesta imo. Explica cómo hacer lo que necesitas saber, que yo también necesitaba saber hacer.
Chris
6
También tuve que llamar .updateValueAndValidity()al control de formulario después de configurar los nuevos validadores.
Keeleon
82

Para agregar a lo que @Delosdos ha publicado.

Establecer un validador para un control en FormGroup: this.myForm.controls['controlName'].setValidators([Validators.required])

Elimine el validador del control en FormGroup: this.myForm.controls['controlName'].clearValidators()

Actualice FormGroup una vez que haya ejecutado cualquiera de las líneas anteriores. this.myForm.controls['controlName'].updateValueAndValidity()

Esta es una forma asombrosa de configurar mediante programación la validación de su formulario.

Shammelburg
fuente
1
Para mí funcionó sin la última línea, estoy bastante seguro de que las nuevas versiones de Angular actualizan la validez del formulario por sí mismas ahora. Pero gracias por contarnos sobre el updateValueAndValiditymétodo, ¡podría ser útil algún día!
Nino Filiu
@NinoFiliu updateValueAndValiditytodavía se usa para realizar la validación y no se maneja de manera diferente en las versiones más recientes de Angular. Lo que sucede es que setValidatorsactualiza los validadores, pero no ejecuta una verificación de validación, y luego se usa updateValueAndValiditypara realizar la validación. Debe configurar los validadores en un punto donde la detección de cambios lo maneja por usted, pero encontrará que el uso updateValueAndValidityen el grupo o control dependiendo del validador que acaba de configurar es crucial: github.com/angular/angular/issues/19622#issuecomment- 341547884 .
mtpultz
4
Estoy en Angular 6 y no podría hacerlo funcionar sin el updateValueAndValidity. ¡Gracias @shammelburg!
Oli Crt
1
En Angular 7 y tampoco funcionaría para mí sin la última línea de actualización.
David Findlay
Si. Funciona sin él updateValueAndValidity(), pero en algunos casos no. si agregó updateValueAndValidity()después setValidators(), afectará inmediatamente los cambios relacionados con el control . Así que es mejor agregar updateValueAndValidity () `.
Jamith NImantha
72

Si está utilizando reactiveFormModule y tiene formGroup definido así:

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)])
});

de lo que puede agregar un nuevo validador ( y mantener los antiguos ) a FormControl con este enfoque:

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 devuelve un validador de composición que contiene todos los validadores definidos previamente.

Eduard Void
fuente
13
Imo, esta debería ser la respuesta aceptada. Demuestra cómo agregar validadores como OP solicitado, pero también le muestra cómo retener validadores previamente configurados; que fue lo primero que busqué en Google cómo hacer después de leer la respuesta aceptada, porque no quería sobrescribir algunos validadores que ya tenía, pero aún necesitaba agregar programáticamente otros. Gracias por esta respuesta @Eduard Void
Chris
3
Estoy de acuerdo con mi predecesor. La pregunta era cómo agregar un nuevo validador al formulario de control, no cómo reemplazarlo .
Plusce
5
Lo hice control.setValidators(control.validator ? [ control.validator, Validators.email ] : Validators.email);para sortear los estrictos controles nulos
William Lohan
3

Creo que la respuesta seleccionada no es correcta, ya que la pregunta original es "cómo agregar un nuevo validador después de crear formControl".

Hasta donde yo sé, eso no es posible. Lo único que puede hacer es crear la matriz de validadores de forma dinámica.

Pero lo que echamos de menos es tener una función addValidator () para no anular los validadores ya agregados a formControl. Si alguien tiene una respuesta para ese requisito, sería bueno que lo publicara aquí.

usuario2992476
fuente
1
Pensarías que control.setValidators(control.validator ? [ control.validator, Validators.email ] : Validators.email);funcionaría.
William Lohan
2
Vea la respuesta de @Eduard Void stackoverflow.com/a/53276815/6656422
William Lohan
3

Además de la respuesta de Eduard Void, aquí está el addValidatorsmétodo:

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 );
};

Al usarlo, puede configurar validadores dinámicamente:

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