forms - page - set title angular 4
Angular 4 quitar el validador requerido condicionalmente (4)
En la aplicación Angular 4 tengo un modelo de formulario como este:
this.form = this._fb.group({
title: ['''', [Validators.required, Validators.minLength(3), Validators.maxLength(50)]],
description: ['''', [Validators.required, Validators.minLength(3)]]
});
Ahora lo que quiero es eliminar dinámicamente solo el validador requerido de la matriz de validadores de control. Algo como esto:
saveDraft() {
this.form.controls[''title''].removeValidator(''required''); //Just a fake implementation for demonstration
}
Esta pregunta no es el duplicado de la pregunta mencionada. Mi caso es diferente, solo quiero eliminar el validador requerido sin saberlo, los otros.
Desafortunadamente, Angular no tiene una capacidad para eliminar el validador en este momento. Todo lo que puede hacer es restablecer los validadores sin el que desea eliminar, por lo que necesita saber qué validadores desea conservar en lugar de cuál desea eliminar. así que esto:
this.form.get(''title'').setValidators([Validators.minLength(3), Validators.maxLength(50)]);
Es lo más cercano que tienes a una función de eliminación. Tampoco puede acceder a los validadores actuales en un control de formulario para intentar escribir su propia función de eliminación. Lo mejor que podría hacer es escribir su propia clase de administrador de validación de control de formulario que pueda realizar un seguimiento de los validadores en un control determinado y administrarlos por usted.
No me gusta limpiar y configurar los validadores, ya que tengo que repetir todos los validadores estáticos (patrones, mínimo, máximo, etc.) solo para tener un validador dinámico "requerido".
Yo uso un validador condicional:
export function conditionalValidator(condFn: (control: AbstractControl) => boolean,
validators: ValidatorFn | ValidatorFn[]): ValidatorFn {
return (control) => {
if (!condFn(control)) {
return null;
}
if (!Array.isArray(validators)) {
return validators(control);
}
return validators.map(v => v(control)).reduce((errors, result) =>
result === null ? errors :
(Object.assign(errors || {}, result))
);
};
}
Entonces puedo mezclar un validador estático con una condición dinámica "requerida":
this.fb.group({name: ['''', [Validators.minLength(4),
conditionalValidator(this.isClientProj, Validators.required)]]}
Donde isClientProj()
es la función de condición (cierre)
Si quieres agregar validación prueba este.
saveDraft() {
this.form.get(''title'').setValidators([Validators.required, Validators.minLength(3)]);
this.form.get(''title'').updateValueAndValidity();
}
Si quieres eliminar los validadores prueba este.
saveDraft() {
this.form.get(''title'').clearValidators();
this.form.get(''title'').updateValueAndValidity();
}
Tuve el mismo problema con guardar la entrada como borrador y preparé la siguiente solución:
@Component({
// ...
})
export class FormComponent{
form: FormGroup;
constructor(private fb: FormBuilder){
this.form = this.fb.group({
name: ['''', Validators.required, Validators.maxLength(20)],
description: ['''', Validators.required, Validators.maxLength(200)],
address: this.fb.group({
line1: ['''', Validators.required, Validators.maxLength(100)],
line2: ['''', Validators.maxLength(100)]
})
});
}
validateDraft(formElement: FormGroup | FormArray | FormControl): boolean {
let result = true;
Object.keys(formElement.controls).forEach(field => {
const control = formElement.get(field);
if(control instanceof FormControl) {
control.markAsTouched({ onlySelf: true });
if(control.errors && control.errors[''required'']) {
control.markAsUntouched({ onlySelf: true });
}
else if(control.invalid) {
result = false;
}
} else if (control instanceof FormArray) {
if (!this.validateDraft(control)) {
result = false;
}
}else if (control instanceof FormGroup) {
if (!this.validateDraft(control)) {
result = false;
}
}
});
}
saveDraft(){
if(this.validateDraft(this.form)){
//save draft - ignore required errors
}
}
save(){
if(this.form.valid){
//save
}
}
}