2017-09-25 206 views
0

我正在開發一個Angular 4.X項目,並且我正在按鈕單擊時創建一些HTML輸入字段(主要是文本類型)。動態創建輸入框工作正常,但我無法對這些字段進行驗證。我收到以下錯誤。Angular 2表單驗證動態字段

無法讀取屬性爲空(...)

我已經創建了一個相同的普拉克的「無效」。以下是我創建的鏈接普拉克 -

https://plnkr.co/edit/PCFD43GK91zo2ivQ9lf7?p=preview 爲了便於參考,請找到下面的代碼 -

//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 {} 

任何幫助,將不勝感激。

回答

0

您正在尋找orderForm內有動態添加的表單域,但並不適用於此。在訪問其值之前,您應該正確查詢表單。我畫下圖將幫助你理解動態創建的表單體系結構。

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

所以IsValidField功能應該得到formArray元素,字段名的index。通過它可以輕鬆查詢表單元素。

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); 
} 

然後在*ngIf發生相應的變化IsValidField函數調用。

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

Demo Plunker

+0

感謝潘卡它確實幫助。你能告訴我如何使用數據填充這些字段,我試圖做到這一點,但它不工作。這是[鏈接]的Plunker(https://plnkr.co/edit/PCFD43GK91zo2ivQ9lf7?p=preview) –

+0

@AmitAnand使用'.patchValue'填充值 –

+0

但是,我將如何做到這一點的多個領域和太動態。你可以看看Plunker併爲我提供解決方案。 –