2017-10-09 64 views
0

我上的角2項目中,我就按一下按鈕動態地創建輸入領域的工作。我正在接受FormArray的幫助。字段和數據提交的創建工作正常,但是當我試圖用一些預定義的數據填充字段時,它不起作用。我爲我的問題創造了一個蹲點。 https://plnkr.co/edit/PCFD43GK91zo2ivQ9lf7?p=preview 這裏我想用對象itemData中的數據填充視圖上的字段。爲了便於參考,以下是角碼 -用數據填充的動態表單控件角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 {} 

任何幫助,將不勝感激。謝謝。

回答

0

一個formArray內部的元件必須是formGroups,而不僅僅是一個對象。

運行您this.itemData.items通過createItems功能,您試圖默認值分配給您的formArray時已經有了。

public loadItems(){ 
    this.orderForm.patchValue({ 
    customerName: this.itemData.customerName, 
    email: this.itemData.email 
    }); 

    this.itemData.forEach((item) => { 
    (<FormArray>this.orderForm.get('items')).push(this.createItem(item)); 
    }); 

} 

當數據來自服務時,不需要重新創建表單,只需要patchValues並相應地更新表單。

PS:您需要修改createItems採取一些輸入數據並返回數據的formGroup。

+0

請您詳細說明一下。我試圖像這樣 公共loadItems(){ this.orderForm = this.formBuilder.group({ 客戶名稱:[this.itemData.customerName,[Validators.required], 電子郵件:[this.itemData.email ,[Validators.required]], 項目:this.formBuilder.array([this.itemData.items]) }); } 但它沒有奏效。 [plunker](https://plnkr.co/edit/PCFD43GK91zo2ivQ9lf7?p=preview) 它拋出以下錯誤 無法找到控制路徑:'項目 - > 0 - >名稱' –

+0

你剛剛複製了該帖子中的內容,當然不會工作,因爲formArray需要formGroups,this.itemData.items只是一個對象 – Sonicd300

+0

非常感謝,它確實有幫助。它的工作現在。唯一的問題是數據填充時,以前的控件(在init中默認創建)也保留在那裏。任何解決此問題的方法? [更新Plunker(https://plnkr.co/edit/PCFD43GK91zo2ivQ9lf7?p=preview) –

0

問題是在你的ItemData的定義嘗試刪除`定義對象:

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"}] 
}; 

,並在您loadItems方法加上括號分配的items值:

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

希望它有幫助:)