2017-08-21 45 views
2

幾天以來,我一直在試圖創建一個表單,它會讓用戶創建一個產品,同時產品的變體可能會有一個與父產品不同的價格。例如大部件是10英鎊,小部件是5英鎊。每次我最終得到的是FormArray中的FormArray,換句話說,我有一個具有一系列變體的產品,這些變體有價格,但也有一系列屬性。問題出現在我嘗試添加控件時,我可以獲得變體價格以顯示出來,但我無法獲取路徑以添加variations.attributes控件,我只是得到一個有關ngFor的錯誤與數組不是[對象,對象]或控制爲空...我有更多的錯誤比我記得!無論如何,我的代碼已被重新​​編寫,並且可能比開始時更糟!Angular 4反應形式 - FormArray在FormArray中無法獲取路徑

第一形式在我的OnInit:

ngOnInit() { 
    this.getAttributes(); // Get Attribute Categories  
    this.form = this.fb.group({ 
     name: [''], 
     price: [''], 
     description: [''], 
     stockRef: [''], 
     attributes: this.fb.array([{ 
      attributeCategoryId: [''], 
      name: [''], 
     }]), 
     variations: this.fb.array([{ 
      vprice: this.vprice, 
      vattributes: this.vattributes 
     }]), 
    }); 
} 

對於法師的產品,其工作正常添加和刪除屬性的部分:

addAttribute(id: any, name: any) { 
    if (!id.value || !name.value) 
     return; 
    this.attributes = <FormArray>this.form.get('attributes'); 
    var newAttribute = this.fb.group({ 
     attributeCategoryId: [id.value], 
     name: [name.value], 
    }); 
    this.newlist.push({ name: [name.value].toString(), attributeCategoryId: [id.value].toString() }); 
    this.attributes.push(newAttribute); 

    id.value = ''; 
    name.value = ''; 
} 
removeAttr(i: any) { 
    this.attributes.removeAt(i); 
    this.list2 = []; 
    this.newlist.splice(i, 1); 
} 

,我加變化的部分,它的工作原理,它仍然有我用來嘗試和複製添加到主要產品的屬性的代碼,到我認爲可行的變體中,但是無法訪問這些值以顯示它們,variations.attributes didn爲路徑工作。

initVariation() { 
    let v = this.fb.group({ 
     price: [''], 
     vattributes: this.attributes //COPIES main attributes    
    }); 
    this.attributes.reset(); //Reset the main attributes as they now  
    return v;    //belong to a variation 
} 
addNewVar() { 
    const control = <FormArray>this.form.controls['variations']; 
    control.push(this.initVariation()); 

} 

,增加屬性的變化,這是不行的,並且是我在我的component.ts問題的部分

addAttrRow() { 
    const control = <FormArray>this.form.controls['variations.vattributes'] 
    control.push(this.initVattr()) 
} 
initVattr() { 
    let va = this.fb.group({ 
     vattributeCategoryId: [''], 
     vname: [''] 
    }) 
    return va; 
} 

最後,我的html這更加的一個爛攤子大聲笑:

<h1>New Product</h1> 
<form [formGroup]="form" (ngSubmit)="save()"> 
    <div class="row"> 
     <div class="col-md-6 col-sm-12"> 
      <div class="form-group"> 
       <label>Product Name</label> 
       <div *ngIf="!form.get('name').valid" class="alert alert-danger"> 
        {{ form.get('name').getError('remote') }} 
       </div> 
       <input [(ngModel)]="name" type="text" formControlName="name" class="form-control"> 
      </div> 
     </div> 
    </div> 
    <div class="row"> 
     <div class="col-md-6 col-sm-12"> 
      <div class="form-group"> 
       <label>Price</label> 
       <div *ngIf="!form.get('price').valid" class="alert alert-danger"> 
        {{ form.get('price').getError('remote') }} 
       </div> 
       <input [(ngModel)]="price" type="number" formControlName="price" class="form-control"> 
      </div> 
     </div> 
    </div> 
    <div class="row"> 
     <div class="col-md-6 col-sm-12"> 
      <div class="form-group"> 
       <label>Product Description</label> 
       <div *ngIf="!form.get('description').valid" class="alert alert-danger"> 
        {{ form.get('description').getError('remote') }} 
       </div> 
       <textarea formControlName="description" class="form-control"></textarea> 
      </div> 
     </div> 
    </div> 
    <div class="row"> 
     <div class="col-md-6 col-sm-12"> 
      <div> 
       <h4>Attributes</h4> 
       <div class="form-inline" > 
        <div class="form-group"> 
         <div formArrayName="attributes"> 
          <select #ac name="attributeCategoryId"> 
           <option value="" selected>Category</option> 
           <option *ngFor="let a of attriblist;let i = index" value="{{a.id}}">{{a.name}}</option> 
          </select> 
          <input #a name="name" placeholder="Attribute name" /> 
         </div> 
        </div> 
        <button type="button" class="btn btn-default" (click)="addAttribute(ac,a)">Add Attribute</button> 
       </div> 
       <br> 
       <table class="table-bordered table table-striped"> 
        <thead> 
         <tr> 
          <th>Attr. Category</th> 
          <th>Attr.</th> 
          <th><button type="button" (click)="addNewVar()" class="btn btn-primary">Add Variation</button></th> 
         </tr> 
        </thead> 
        <tbody> 
         <tr *ngFor="let a of form.value.attributes; let i = index;" > 
          <td *ngIf="i > 0">{{a.attributeCategoryId}}</td> 
          <td *ngIf="i > 0">{{a.name}}</td> 
          <td *ngIf="i > 0"><button (click)="removeAttr(i)" class="btn btn-danger">X</button></td> 
         </tr> 
        </tbody> 
       </table> 

      </div> 
     </div> 
    </div> 
    <!--Variations Start--> 
    <div class="row" formArrayName="variations"> 
     <div *ngFor="let variation of form.controls.variations.controls; let i=index" [formGroupName]="i"> 
      <h5>Variation #{{ i + 1 }}</h5> 
      <p></p> 
      <div class="form-group"> 
       <label>Variation Price</label> 
       <input name="vprice" style="max-width:50px" class="form-control"> 
      </div> 
      <table> 
       <thead> 
        <tr> 
         <th>Attr. Category</th> 
         <th>Attr.</th> 
         <th><button class="btn btn-success" (click)="addAttrRow()">+</button></th> 
        </tr> 
       </thead> 
       <tbody name="vattributes"> 
        <tr *ngFor="let attribute of variation.get('vattributes'); let ii = index;"> 
         <td><input type="text" name="vattributeCateforyId" /></td> 
         <td><input type="text" name="vname" /></td> 
         <td><button (click)="removeVAttr(ii)" class="btn btn-danger">X</button></td> 
        </tr> 
       </tbody> 
      </table> 
      <button class="btn btn-danger" (click)="removeVariation(i)">Delete</button> 

     </div> 
     </div> 
    <!--Variations End--> 
    <br> 
    <p> 
     <button type="submit" class="btn btn-primary">Save</button> 
    </p> 
</form> 
+0

我有疑問,我們可以瞭解您的屬性和變化應該鏈接,但與此https://plnkr.co/edit/9FcYTmz15t7hkVlTtBdD?p=preview我刪除用戶後的屬性列表開始增加了具有這些屬性 – yurzui

+0

@yurzui啊新變化所以不用加在聲明的控制/陣列,以及添加屬性行變化時使用「常量控制= this.form.get([‘變化’,索引‘vattributes’]);」 (我錯過了從路徑索引)現在我明白了當我無法找到控制變體> 0>變量時的錯誤!謝謝。如果你能做出這個答案,我會相應地標記它。 –

回答

3

我看到你的代碼中的很多錯誤。

例如

1)你應該知道,我們需要的不是忘掉索引時處理得到控制從FormArray

所以不是

const control = <FormArray>this.form.controls['variations.vattributes']; 

我們應該使用

addAttrRow(index) { 
    const control = <FormArray>this.form.get(['variations', index, 'vattributes']); 

2)如果您沒有指定button的類型,則它將有submit作爲默認值。

<button class="btn btn-success" (click)="addAttrRow()">+</button> 

它可能導致不可預知的情況。

所以嘗試指定type="button"

3)您遍歷對象

*ngFor="let attribute of variation.get('vattributes'); 

,而你需要數組遍歷

*ngFor="let variation of form.controls.variations.controls; 

我創建Plunker Example,可以幫助你意識到你做錯了什麼

相關問題