web-dev-qa-db-fra.com

Angular 4 retirer le validateur requis sous condition

Dans l'application Angular 4, j'ai un modèle de formulaire comme celui-ci:

this.form = this._fb.group({
    title: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(50)]],
    description: ['', [Validators.required, Validators.minLength(3)]]
});

Ce que je veux maintenant, c’est de ne supprimer dynamiquement que le validateur requis du tableau des validateurs de contrôle. Quelque chose comme ça:

saveDraft() {
    this.form.controls['title'].removeValidator('required'); //Just a fake implementation for demonstration
}

Cette question n'est pas le doublon de la question mentionnée. Mon cas est différent Je veux juste supprimer le validateur requis sans le savoir, les autres.

19
Ali Shahzad

si vous voulez ajouter une validation, essayez celui-ci.

saveDraft() {
   this.form.get('title').setValidators([Validators.required, Validators.minLength(3)]);
   this.form.get('title').updateValueAndValidity();
}

si vous voulez supprimer les validateurs, essayez celui-ci.

saveDraft() {
 this.form.get('title').clearValidators();
 this.form.get('title').updateValueAndValidity();
}
49
Singam

Je n'aime pas effacer et définir les validateurs, car je dois répéter tous les validateurs statiques (modèles, min, max, etc.) juste pour avoir un validateur dynamique "obligatoire".

J'utilise un validateur conditionnel:

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

Je peux alors mélanger un validateur statique avec une condition dynamique "requise":

this.fb.group({name: ['', [Validators.minLength(4),
                 conditionalValidator(this.isClientProj, Validators.required)]]}

isClientProj() est la fonction de condition (fermeture)

3
Alex R

Malheureusement, Angular n’a pas de fonctionnalité removeValidator pour le moment. Tout ce que vous pouvez faire est de réinitialiser les validateurs sans celui que vous souhaitez supprimer. Vous devez donc savoir quels validateurs vous souhaitez conserver plutôt que celui que vous souhaitez supprimer. donc ça:

this.form.get('title').setValidators([Validators.minLength(3), Validators.maxLength(50)]);

Est-ce le plus proche d'une fonction de suppression? Vous ne pouvez pas accéder aux validateurs actuels sur un formulaire de contrôle pour essayer d’écrire votre propre fonction de suppression. Le mieux que vous puissiez faire est d’écrire votre propre classe de gestionnaire de validation de contrôle de formulaire qui peut suivre les validateurs d’un contrôle donné et les gérer pour vous.

1
bryan60

J'ai eu le même problème avec l'enregistrement de l'entrée en tant que brouillon et préparé la solution suivante:

@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
        }
    }
}
0
kalinowski