2017-08-21 5 views
2

Seit ein paar Tagen habe ich versucht, ein Formular zu erstellen, das einem Benutzer ein Produkt zu erstellen und gleichzeitig Variationen des Produkts, die eine haben können anderer Preis zum Elternprodukt. zB Großes Widget ist £ 10, Kleines Widget ist £ 5. Was ich jedes Mal erhalte ist ein FormArray in einem FormArray, mit anderen Worten, ich habe ein Produkt mit einer Reihe von Variationen, diese Varianten haben einen Preis, aber sie haben auch eine Reihe von Attributen. Das Problem kommt, wenn ich versuche, die Steuerelemente hinzuzufügen, kann ich den Variationspreis erhalten, um gut zu zeigen, aber ich kann den Pfad nicht erhalten, um die variations.attributes Steuerelemente hinzuzufügen, ich bekomme nur einen Fehler über ngFor nur arbeiten Bei Arrays, die nicht [Object, Object] oder Control sind, ist null ... Ich hatte mehr Fehler als ich mich erinnern kann! sowieso auf meinen Code, der viel neu geschrieben wurde, und ist wahrscheinlich schlimmer als es begann!Angular 4 reaktives Formular - FormArray Innerhalb von FormArray kann Pfad nicht erhalten

zuerst die Form in meinem 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 
     }]), 
    }); 
} 

Der Abschnitt zum Hinzufügen und Attribute für den Master-Produkt zu entfernen, der gut arbeitet:

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

Der Teil, wo ich Variationen hinzufügen, die funktioniert , es hat immer noch den Code, den ich verwendet habe, um die Attribute, die zum Hauptprodukt hinzugefügt wurden, in die Variation zu kopieren, was meiner Meinung nach funktionierte, aber ich konnte einfach nicht auf die Werte zugreifen, um sie anzuzeigen, variations.attributes didn arbeite nicht für den Weg.

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

} 

Der Teil, der Attribute der Variation fügt hinzu, was nicht funktioniert, und ist, wo ich Probleme in meinem component.ts mit

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

, schließlich mein html, die noch mehr von ein Chaos lol:

<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

Ich habe Zweifel darüber, wie Ihre Attribute und Variationen verknüpft werden sollten, aber wir können mit diesem https://plnrkr.co/edit/9FcYTmz15t7hkVlTtBdD?p=preview beginnen Ich entferne die Attributliste, nachdem der Benutzer eine neue Variante mit diesen Attributen hinzufügt – yurzui

+0

@yurzui Ahh Fügen Sie also die Steuerelemente/Arrays nicht in die Deklaration ein, und wenn Sie die Attributzeilen zur Variation hinzufügen, verwenden Sie "const control = this.form.get (['variations', index, 'vattributes']);" (Ich habe den Index vom Pfad verpasst) Jetzt verstehe ich den Fehler, wenn ich keine Kontrolle mit Variationen> 0> VATTRIBUTS finden konnte! Vielen Dank. Wenn Sie das beantworten können, markiere ich es entsprechend. –

Antwort

3

Ich sehe eine Menge Fehler in Ihrem Code.

Zum Beispiel

1) sollten Sie sich bewusst sein, dass wir über Index nicht vergessen müssen, wenn viel mit bekommen Kontrolle von FormArray

Also statt

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

wir nutzen sollten

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

2) Wenn Sie für button keinen Typ angeben, wird submit als Standardwert verwendet.

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

und es kann zu unvorhersehbaren Situationen führen.

versuchen So type="button"

3) Sie über das Objekt iterieren angeben

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

während Sie Array müssen iterieren

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

I erstellt Plunker Example, dass Sie helfen können Erkenne, was du falsch gemacht hast

Verwandte Themen