2017-10-20 7 views
0

J'utilise FormBuilder pour construire un formulaire:Comment ajouter dynamiquement des validateurs aux formulaires dans Angular 2 - 4 en utilisant FormBuilder?

this.myForm = this.fb.group({ 
    'name': new FormControl(null, Validators.min(5)), 
    'description': new FormControl(null, Validators.min(60)) 
}); 

Le problème est que je dois aussi valider si elle est nécessaire et je l'obtenir de la configuration par une carte construite comme ceci:

map = new Map<string, boolean>(); 
map.set('name', true); 
map.set('description', false); 

Le problème peut être résolu comme suit:

this.myForm = this.fb.group({ 
    'name': this.map.get('name') ? new FormControl(null, Validators.compose([Validators.required, Validators.min(5)])) : new FormControl(null, Validators.min(5)), 
    'description': this.map.get('description') ? new FormControl(null, Validators.compose([Validators.required, Validators.min(60)])) : new FormControl(null, Validators.min(60)) 
}); 

qui fonctionne imaginer, mais dans une grande application avec plusieurs formes avec beaucoup de champs réels est inconfortable de cette façon de le faire. Idéalement, cela ressemblerait à ceci:

Object.keys(this.myForm.controls).forEach(key => { 
    if (map.get(key)) { 
    this.myForm.get(key).setValidators(this.myForm.get(key).getValidators().push(Validators.required)) 
    } 
}); 

Bien sûr, cela ne fonctionne pas. Donc, si quelqu'un qui a déjà résolu cela ou a un bon moyen de faire ce qui est décrit ci-dessus, je vais vous remercier beaucoup. Merci d'avance!!!

Mise à jour: Le problème peut être réduit à "comment obtenir tous les validateurs associés à un FormControl". Je ne pense pas qu'il y ait une solution définitive à cette question ->https://github.com/angular/angular/issues/13461

+0

pourquoi cette méthode ne fonctionne pas? –

+0

La méthode .getValidators() n'existe pas dans Angular 2 - 4, ou du moins je n'ai pas trouvé quelque chose de similaire. Cependant, si une méthode .setValidators() existe dans Angular 2 - 4. –

+0

vérifiez ma réponse –

Répondre

1

ici est une solution simple, je l'ai expliqué dans les commentaires:

Object.keys(this.myForm.controls).forEach(key => { 
     // if it needs to be required 
     if (map.get(key)) { 
      // you have first to check if it already contains validator.required. 
      let validators = this.myForm.controls[key].validator(this.myForm.controls[key]); 
      // if it contains it -> {required: true}; 
      // if it doesn't contains it you can now add the required validator 
      if(validators && !validators.required){ 
       let exisitingValidators = this.myForm.controls[key].validators;   
       this.myForm.controls[key].setValidators(Validators.compose([...existingValidators ,Validators.required])); 
       // call updateValueAndValidity to apply the new validators on the control 
       this.myForm.controls[key].updateValueAndValidity();     
     } 
    }); 

Hope it helps :)

+0

merci pour votre réponse. 'let validators = this.myForm.controls [clé] .validator ('');' ceci retourne les validateurs? –

+0

y a-t-il des erreurs? ça marche? @ RidelHernándezInfante –

+0

Cela ne fonctionne pas, 'let validators = this.myForm.controls [clé] .validator ('');' renvoie l'erreur suivante: Erreur: (72, 107) TS2345: l'argument de type '' n'est pas assignable au paramètre de type 'AbstractControl'. Je ne pense pas qu'il renvoie les validateurs –

0

Juste nettoyé/refactorisé au-dessus du code. Créer une fonction de composition Veuillez regarder

// composer function 
const composer = (control: FormControl, ...validators) => { 
    control.setValidators(Validators.compose([...validators])); 
} 

for (let name of Object.keys(grp)) { 
    let control = this.heroForm.controls[name]; 
    if (map.has(name)) { 
    let validators = control.validator(control); 
    if (validators && !validators.required) { 
     let exisitingValidators = control.validators; 
     composer(control, ...exisitingValidators, Validators.required); 
    } 
    } 
} 
+0

merci pour votre réponse, je vais essayer d'optimiser une fois que vous avez la solution dans le domaine de l'angulaire, merci –

+0

Pas encore implémenté. mais vous pouvez voir pour https://github.com/angular/angular/issues/13461 – xdeepakv

+0

Par ailleurs, je ne recommanderai pas d'utiliser push (état de mutation). C'est difficile de gérer l'état. A fait quelques modifications, peut-être que vous pouvez essayer quelque chose comme ceci comme code propre. – xdeepakv