2017-10-09 1 views
0

Je travaille sur un projet Angular 2 où je crée dynamiquement des champs de saisie en cliquant sur le bouton. Je prends l'aide de FormArray pour la même chose. La création de champs et la soumission de données fonctionnent correctement, mais lorsque j'essaie de remplir les champs avec des données prédéfinies, cela ne fonctionne pas. J'ai créé un plunker pour mon problème. https://plnkr.co/edit/PCFD43GK91zo2ivQ9lf7?p=preview Ici, je veux remplir les champs de la vue avec les données de l'objet itemData. Pour faciliter la consultation, le code angulaire est le suivant -Remplissage de contrôles de formulaire dynamiques avec des données dans Angular 2

//our 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> 
        <div> 
         <label>Customer Name</label> 
         <input type="text" formControlName="customerName"/> 
         <small *ngIf="IsValidField('customerName')" class="text-danger"> 
          Customer Name is required 
         </small> 
        </div> 
        <br/> 
        <div> 
         <label>Customer Email</label> 
         <input type="text" formControlName="email"/> 
         <small *ngIf="IsValidField('email')" class="text-danger"> 
          Email is required 
         </small> 
        </div> 
        </div> 
        <br/> 
        <div formArrayName="items" *ngFor="let item of items.controls; let i = index;"> 
        <div [formGroupName]="i"> 
         <div> 
         <label>Item Name</label> 
         <input type="text" formControlName="name" placeholder="Item name"/> 
         <small *ngIf="IsValidField('name',i)" class="text-danger"> 
          Item Name is required 
         </small> 
         </div> 
         <br/> 
         <div> 
         <label>Item Description</label> 
         <input type="text" formControlName="description" placeholder="Item description"/> 
         <small *ngIf="IsValidField('description',i)" class="text-danger"> 
          Description is required 
         </small> 
         </div> 
         <br/> 
         <div> 
         <label>Item Price</label> 
         <input type="text" formControlName="price" placeholder="Item price"/> 
         <small *ngIf="IsValidField('price',i)" class="text-danger"> 
          Price is required 
         </small> 
         </div> 
         <br/> 
        </div> 
        </div> 
        <button type="submit">Save</button> 
        <button type="button" (click)="addItem()">Add More</button> 
        <button type="button" (click)="loadItems()">Load Items</button> 
       </form> 
       <div>`, 
}) 

export class App { 

    constructor(private formBuilder: FormBuilder) { } 

    public orderForm: FormGroup; 
    public formSubmitAttempt: boolean; 
    public itemData:any=`{ 
    "customerName":"Customer 1","email":"[email protected]", 
    "items":[{"name":"Item 1","description":"Item 1 Descr","price":"100"}, 
      {"name":"Item 2","description":"Item 2 Descr","price":"200"}, 
      {"name":"Item 3","description":"Item 3 Descr","price":"300"}] 
    }`; 

    ngOnInit() { 
    this.orderForm = this.formBuilder.group({ 
     customerName: ['',[Validators.required]], 
     email: ['',[Validators.required]], 
     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)]*")]] 
    }); 
    } 

    public loadItems(){ 
    this.orderForm = this.formBuilder.group({ 
     customerName: [this.itemData.customerName,[Validators.required]], 
     email: [this.itemData.email,[Validators.required]], 
     items: this.itemData.items 
    }); 
    } 

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

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

    public OnSubmit(formValue: any) { 
    this.formSubmitAttempt = true; 
    console.log(JSON.stringify(formValue)); 
    } 

    public IsValidField(field: string, i?:number) { 
    if(i!=null) { 
     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.formSubmitAttempt); 
    } else { 
     return (this.orderForm.get(field).invalid && this.orderForm.get(field).touched) || (this.orderForm.get(field).invalid && this.formSubmitAttempt);    
    } 
    } 
} 

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

Toute aide serait appréciée. Merci.

Répondre

0

Les éléments à l'intérieur d'un formulaire doivent être formGroups, pas seulement un objet.

Exécutez votre this.itemData.items via la fonction createItems que vous avez déjà en essayant d'assigner des valeurs par défaut à votre formArray. Pas besoin de recréer le formulaire lorsque les données proviennent d'un service, juste patchValues ​​et mettre à jour le formulaire en conséquence. PS: vous devez modifier createItems pour prendre des données d'entrée et renvoyer le formGroup avec des données.

+0

Pourriez-vous s'il vous plaît élaborer un peu. Je l'ai essayé comme ceci { this.orderForm = this.formBuilder.group ({ customerName loadItems public(): [this.itemData.customerName, [Validators.required]], email: [this.itemData.email , [Validators.required]], éléments: this.formBuilder.array ([this.itemData.items]) }); } Mais cela n'a pas fonctionné. [plunker] (https://plnkr.co/edit/PCFD43GK91zo2ivQ9lf7?p=preview) Il lance erreur suivante Impossible de trouver le contrôle avec le chemin: 'articles -> 0 -> nom' –

+0

vous venez de copier ce qui est dans le post , bien sûr ne va pas marcher, car formArray a besoin de formerGroups, this.itemData.items est juste un objet – Sonicd300

+0

Merci beaucoup, ça m'a vraiment aidé. Ça marche maintenant. Le seul problème est lorsque les données sont remplies, les contrôles précédents (créés par défaut sur init) restent également là. Un travail pour ça? [Plunker mis à jour] (https://plnkr.co/edit/PCFD43GK91zo2ivQ9lf7?p=preview) –

0

le problème est dans la définition de vos itemData essayez de supprimer le ` pour définir l'objet:

public itemData:any={ 
    "customerName":"Customer 1","email":"[email protected]", 
    "items":[{"name":"Item 1","description":"Item 1 Descr","price":"100"}, 
      {"name":"Item 2","description":"Item 2 Descr","price":"200"}, 
      {"name":"Item 3","description":"Item 3 Descr","price":"300"}] 
}; 

et dans votre méthode ajouter entre parenthèses loadItems pour affecter la valeur de items:

public loadItems(){ 
    this.orderForm = this.formBuilder.group({ 
     customerName: [this.itemData.customerName,[Validators.required]], 
     email: [this.itemData.email,[Validators.required]], 
     items: [this.itemData.items] 
     }); 
} 

espérons que cela aide :)