2017-11-19 6 views
0

ich eine Top-Level-Komponente haben, die diese in der Vorlage hat:Angular4 - 3-Ebene benutzerdefinierte Komponenten, Enkel (ngModelChange) sieht immer gleichen Großeltern

<cw-card-list [cards]="cards"> 
    </cw-card-list> 

Die Karten aus der API aufgefüllt werden, wenn die Bauteilbelastungen :

private getCards(): void{ 
    this._cardService.getCards().subscribe(
     result => { 
     this.cards = result; 
     } 
    ); 
    } 

Die Karte-Liste Komponente ist sehr einfach:

<div *ngFor="let card of cards; let i = index"> 
    <cw-card-list-item 
     [card]="card" [index]="i"> 
    </cw-card-list-item> 
    </div> 

Sie können sich e, die jede Karte in der Liste einen Eingang in der Karte-list-item Kind ist:

export class CardListItemComponent implements OnInit, AfterViewInit { 
    @Input() card: Card; 
    @Input() index: number; 
... 

Schließlich jede dieser list-item-Komponenten hat auch ein Kind:

<cw-checklist-show [template]="card.template" 
</cw-checklist-show> 

export class ChecklistShowComponent implements OnInit { 
    @Input() template: Template 
... 

Alles funktioniert, Alle Daten werden angezeigt.

jedoch innerhalb dieser letzten Komponente gibt es eine Checkbox, die auf eine Eigenschaft gebunden ist 'is_completed' jedes Kind (a TemplateItem):

<div *ngFor="let child of template.template_items; let i=index"> 
      <input id="checkbox-{{i}}" type="checkbox" 
      [ngModel]="child.is_completed" 
      (ngModelChange)="onItemIsCompletedChange(i)"> 
</div> 

Jedes Mal, wenn der (ngModelChange) Ereignis feuert sie immer ändert die 'is_completed' Eigenschaft der Vorlage für die erste Karte in der Liste, nicht die angeklickte.

Warum passiert das? Ich habe sogar versucht, ein Ausgabeereignis mit dem übergeordneten Element zu verschalten, und die Konsole hat die Vorlage protokolliert - und es listet immer die gleiche Vorlage, Element [0] im Kartenlisten-Array auf!

Aber wenn ich this.cards in den Großeltern console.log, es zeigt die richtige Vorlage wird an jede Karte angebracht!

DATA STRUCTURE

Jede Karte hat eine Vorlage, wie folgt aus:

import { Template } from './template'; 
export class Card { 
    constructor() { 
    } 

    public id: string 
    public customer_id: string 
    public template: Template 
    public follow_up: Date 
    public is_new: boolean = true 
} 

jede Vorlage eine Reihe von TemplateItem hat:

import { TemplateItem } from './template-item'; 

export class Template { 
    constructor(
) {} 

    public id: string 
    public account_id: string 
    public name: string 
    public template_items: Array<TemplateItem> 
    public template_type: string 
    public status: string 
} 

Jede TemplateItem ist wie folgt:

export class TemplateItem { 
    constructor(
) {} 

    public id: string 
    public template_id: string 
    public sort: number 
    public content: string 
    public item_type: string 
    public is_completed: boolean = false 
} 

Antwort

0

Dies ist vielleicht nicht sofort offensichtlich, wenn Sie gewohnt sind, modellgetriebene Formulare zu erstellen, wie ich bin, aber die ID der Eingabe ist von entscheidender Bedeutung.

Da meine Eingaben wurden den INDEX verwenden, bedeutet dies, dass die Kontrollkästchen auf meiner Seite nicht anders ids haben:

checkbox-{{i}} 

Das bedeutet, dass es immer löst das Ereignis auf dem Kontrollkästchen in der ersten Karte klicken (zB Checkbox-0, Checkbox-1) da offensichtlich jedes Enkelkind (TemplateItem) ein Array von 0 ... n ist.

So ist die Lösung:

 <input id="checkbox-{{child.id}}-{{i}}" type="checkbox" 
     [ngModel]="child.is_completed" 
     (ngModelChange)="onItemIsCompletedChange(i)"> 

Jetzt jede Checkbox hat eine eindeutige ID, die spezifisch für die ID des Enkelkind TemplateItem.

Verwandte Themen