2017-09-25 1 views
0

Je travaille sur un projet Angular 4.X et je crée des champs de saisie HTML (principalement du type texte) en cliquant sur le bouton. La création dynamique des zones de saisie fonctionne correctement, mais je ne suis pas en mesure d'implémenter la validation dans ces zones. Je reçois l'erreur suivante.Angular 2 Validation de formulaire pour les champs dynamiques

Impossible de lire la propriété 'invalide' null (...)

J'ai créé un Plunk pour la même. Voici le lien pour le Plunk que j'ai créé -

https://plnkr.co/edit/PCFD43GK91zo2ivQ9lf7?p=preview Pour faciliter s'il vous plaît trouver le code ci-dessous -

//Root app component 
import {Component, NgModule} from '@angular/core' 
import {BrowserModule} from '@angular/platform-browser' 
import { FormBuilder, FormGroup, Validators, FormArray, FormControl } from '@angular/forms'; 
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 

@Component({ 
    selector: 'my-app', 
    template: `<hr> 
       <div> 
       <form [formGroup]="orderForm" (ngSubmit)="OnSubmit(orderForm.value)"> 
        <div> 
        <input type="text" formControlName="customerName"/> 
        <input type="text" formControlName="email"/> 
        </div> 
        <div formArrayName="items" *ngFor="let item of items.controls; let i = index;"> 
        <div [formGroupName]="i"> 
         <input type="text" formControlName="name" placeholder="Item name"/> 
         <small *ngIf="IsValidField('name')" class="text-danger"> 
         Name is required 
         </small> 
         <input type="text" formControlName="description" placeholder="Item description"/> 
         <small *ngIf="IsValidField('description')" class="text-danger"> 
         Description is required 
         </small> 
         <input type="text" formControlName="price" placeholder="Item price"/> 
         <small *ngIf="IsValidField('price')" class="text-danger"> 
         Price is required 
         </small> 
        </div> 
        Chosen name: {{ orderForm.controls.items.controls[i].controls.name.value }} 
        </div> 
        <button type="submit">Save</button> 
        <button type="button" (click)="addItem()">Add More</button> 
       </form> 
       <div>`, 
}) 

export class App { 

    constructor(private formBuilder: FormBuilder) { } 

    public orderForm: FormGroup; 



    ngOnInit() { 
     this.orderForm = this.formBuilder.group({ 
     customerName: '', 
     email: '', 
     items: this.formBuilder.array([ this.createItem()]) 
     }); 
    } 

createItem(): FormGroup { 
    return this.formBuilder.group({ 
     name: ['',[Validators.required,Validators.maxLength(10)]], 
     description: '', 
     price: ['',[Validators.required,Validators.pattern("[(0-9)*]")]] 
    }); 
    } 

    get items(): FormArray { 
    return this.orderForm.get('items') as FormArray; 
    }; 

    addItem(): void { 
    this.items.push(this.createItem()); 
    } 

    public OnSubmit(formValue: any) { 
     console.log(JSON.stringify(formValue)); 
    } 

    public IsValidField(field: string) { 
     return (this.orderForm.get(field).invalid && this.orderForm.get(field).touched) || (this.orderForm.get(field).invalid && this.orderForm); 
    } 

} 

@NgModule({ 
    imports: [ BrowserModule, FormsModule, ReactiveFormsModule ], 
    declarations: [ App ], 
    bootstrap: [ App ] 
}) 
export class AppModule {} 

Toute aide serait appréciée.

Répondre

0

Vous recherchez des champs de formulaire ajoutés dynamiquement à l'intérieur de orderForm, qui n'est pas disponible ici. Vous devez interroger le formulaire correctement avant d'accéder à sa valeur. Je dessine ci-dessous figure qui vous aidera à comprendre comment l'architecture de forme créée dynamiquement.

orderForm (FormGroup) 
    | 
    - Items (FormArray) 
    | 
    - 0 (FormGroup) 
     - name 
     - description 
     - price 
    | 
    - 1 (FormGroup) 
     - name 
     - description 
     - price 
    | 
    |......... 

donc fonction IsValidField doit obtenir le index de l'élément formArray et le nom de domaine. Par lequel vous pouvez facilement interroger l'élément de formulaire.

public IsValidField(i: number, field: any) { 
    var f = this.orderForm 
      .get('items') //retrieve items FormArray 
      .get(i.toString()) //retrieve items FormGroup 
      .get(field); //retrieve items form field 
    return (f.invalid && f.touched) || (f.invalid && this.orderForm); 
} 

Puis changer IsValidField appel de fonction *ngIf en conséquence.

*ngIf="IsValidField(i, 'name')" 
*ngIf="IsValidField(i, 'description')" 
*ngIf="IsValidField(i, 'price')" 

Demo Plunker

+0

Merci Pankaj cela m'a vraiment aidé. Pourriez-vous s'il vous plaît me dire comment peupler ces champs avec des données, j'essaie de le faire mais ça ne fonctionne pas. Voici le Plunker pour cela [link] (https://plnkr.co/edit/PCFD43GK91zo2ivQ9lf7?p=preview) –

+0

@AmitAnand utilise '.patchValue' pour remplir les valeurs –

+0

Mais comment le ferais-je pour les champs multiples et que trop dynamique. Pourriez-vous s'il vous plaît regarder dans le Plunker et me fournir une solution. –