2017-10-18 21 views
1

J'utilise les formes réactives d'Angular et j'aimerais appliquer un style css aux contrôles dans un FormArray en fonction de la valeur de la propriété invalide du contrôle. J'ai trouvé l'approche suivante mais je pense que l'expression à l'intérieur de la propriété ngClass est trop longue et complexe. Existe-t-il un moyen plus succinct d'accéder à la propriété invalide pour un contrôle dans un FormArray?Accès à l'état du validateur dans un template pour un contrôle dans un FormArray

Modèle:

<form [formGroup]="myForm" class="form-horizontal"> 
    <div class="form-group" [ngClass]="{'has-error': myForm.controls.name.invalid }"> 
     <label class="control-label">Name</label> 
     <input formControlName="name" type="text" class="form-control" /> 
    </div> 
    <div formArrayName="array1"> 
     <div *ngFor="let f of array1_FA.controls; let i = index" [formGroupName]="i"> 
      <div> 
       <div class="form-group" 
        [ngClass]="{'has-error': myForm.controls.array1.at(i).controls.question.invalid}"> 

        <label class="control-label">Question #{{i+1}}</label> 
        <input formControlName="question" class="form-control" type="text" /> 
       </div> 
       <div class="form-group" 
        [ngClass]="{'has-error': myForm.controls.array1.at(i).controls.response.invalid}"> 

        <label class="control-label">Answer #{{i+1}}</label> 
        <input formControlName="response" class="form-control" type="text" /> 
       </div> 
      </div> 
     </div> 
    </div> 
</form> 

Composant:

import { Component } from '@angular/core'; 
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; 

@Component({ 
    selector: 'form-array-validation', 
    templateUrl: './form-array-validation.component.html' 
}) 

export class FormArrayValidationComponent { 

    myForm: FormGroup; 
    questions = ['Q1', 'Q2', 'Q3', 'Q4']; 

    constructor(private fb: FormBuilder) { 
     this.createForm(); 
    } 

    createForm() { 
     this.myForm = this.fb.group({ 
      name: ['Name1', Validators.required], 
      array1: this.fb.array(this.questions.map(val => this.fb.group({ 
       question: [val, Validators.required], 
       response: [null, Validators.required] 
      }))) 
     }); 
    } 

    get array1_FA(): FormArray { 
     return this.myForm.get('array1') as FormArray; 
    }; 
} 
+0

Avez-vous regardé .get? Cela fournit une syntaxe de raccourci: https://angular.io/guide/reactive-forms#inspect-formcontrol-properties – DeborahK

+0

Je pense que .get le rend plus lisible mais toujours très proche. 'myForm.get ('array1'). at (i) .get ('question'). invalid' – EricAZ

Répondre

0

Dans ce cas, vous pouvez utiliser votre f dans l'itération dans le modèle:

*ngFor="let f of array1_FA.controls; 

ce qui rend votre code un peu plus court/plus propre, donc au lieu de:

[ngClass]="{'has-error': myForm.controls.array1.at(i).controls.question.invalid}"> 

do:

[ngClass]="{'has-error': f.get('question').invalid} 

ou

[ngClass]="{'has-error': f.controls.question.invalid} 
+0

Parfait! Je me suis juste rappelé de la liaison de classe angulaire et j'utilise: '[class.has-error] =" f.get ('question'). Invalide "' – EricAZ

+0

chose sûre, je n'ai pas regardé même à l'implémentation de classe, juste regardé le "raccourcissement" des chemins de propriété, en ignorant le reste: D Mais oui, c'est un mouvement sage :) – Alex

1

Lorsqu'un groupe de formulaire n'est pas valide, angulaire ajouter la classe ng-invalide là-dessus. Vous pouvez l'utiliser pour supprimer complètement la liaison de classe.

+0

Dans cette instance particulière, j'essaie d'utiliser des classes css existantes provenant d'un framework tiers. – EricAZ

0

Vous devriez être en mesure de faire quelque chose comme ceci:

myForm.get(`array1.${i}.question`).invalid 

Notez que ce sont les tiques dos.

(je devais changer une réponse parce que les commentaires étaient en train de manger les tiques arrière.)

+0

Ceci est une idée intéressante, mais je ne pense pas que je peux utiliser les backticks à l'intérieur d'un modèle, au moins, je n'ai pas été en mesure de faire ce travail. – EricAZ