2016-07-15 19 views
0

ich Plunker hier geschaffen haben:Angular 2 Zweiweg-Komponente nicht bindend Eltern nicht nennen ngOnChange

http://plnkr.co/edit/8bwqkYQ6tqrpGwHT588y?p=preview

, der das Problem zeigt.

Grundsätzlich habe ich 2 Komponenten. Die erste Komponente hat eine 2-Wege-Bindung einer Eigenschaft an die untergeordnete Komponente.

Meine Eltern Komponente ist:

import { Component, Input, Output, EventEmitter } from '@angular/core' 
import { ChildComponent } from "./childComponent" 

@Component({ 
    selector: 'parentComponent', 
    template: ` 
    <div> 
     <a href="#" (click)="selectedId = 0">Reset</a><br> 
     <div>Parent SelectedId: {{selectedId}}</div> 
     <childComponent [(selectedId)]="selectedId"></childComponent> 
    </div> 
    `, 
    directives: [ChildComponent] 
}) 

export class ParentComponent { 
    @Input() selectedId: number; 

    ngOnChanges(changes) { 
     console.log("Parent changes called!"); 
    } 
} 

und mein Kind Komponente:

import { Component, Input, Output, EventEmitter } from '@angular/core' 

@Component({ 
    selector: 'childComponent', 
    template: ` 
    <div> 
     <div>Child SelectedId: {{selectedId}}</div> 
    </div> 
    `, 
    directives: [] 
}) 

export class ChildComponent { 
    @Input() selectedId: number; 
    @Output() selectedIdChange: EventEmitter<number> = new EventEmitter<number>(); 

    constructor() { 
     setTimeout(() => { 
     this.selectedId = 100; 
     this.selectedIdChange.emit(this.selectedId); 
     }, 2000); 
    } 

    ngOnChanges(changes) { 
     console.log("Child changes called!"); 
    } 
} 

Im Kind, ich einen Timeout den Wert des SelectedID programmatisch nach 2 Sekunden zu ändern, dann strahlen die Wert zurück zum Elternteil.

Das alles funktioniert super, bis auf eine Sache ... der ngOnChange des Elternteils wird nur einmal aufgerufen.

Ich würde denken, dass die Eltern würden sehr gerne wissen, ob das Kind den Wert geändert hat, oder sonst was ist der Punkt der 2-Wege-Bindung?

Was fehlt mir hier?

Antwort

1

Der ngOnChange des übergeordneten Elements wird nur aufgerufen, wenn sich die App selectedId ändert, da die Eingabeeigenschaft von ParentComponent an diese gebunden ist.

Wenn Sie wollen, dass die Eltern über Änderungen in dem Kind gemacht werden, binden an das xChange Ereignis (wo x der Name der Eingabeeigenschaft ist) – dh brechen die Eigenschaft und Ereignisbindungen auf:

<childComponent [selectedId]="selectedId" (selectedIdChange)="changed($event)"></childComponent> 
changed(newValue) { 
    console.log('newValue', newValue); 
    this.selectedId = newValue; 
} 

Plunker

+1

Kann ich nur sagen, das ist wirklich, wirklich dumm. Wann möchten Sie NICHT, dass Ihre Elternkomponente benachrichtigt wird, dass sich die Eigenschaft geändert hat, wenn Sie sie explizit als 2-Wege-Bindung einrichten? Es sollte das Änderungsereignis automatisch den ganzen Weg über sprudeln lassen. – Scottie

+0

@Scottie, manchmal möchten Sie nur, dass das übergeordnete Element (z. B. die Elternansicht) aktualisiert wird, und Sie müssen nicht benachrichtigt werden, da Sie keine Logik ausführen müssen, wenn das untergeordnete Element eine Änderung vornimmt. Und Sie haben Recht, Ereignisse, die von EventEmitter ausgesendet werden, platzen nicht. Wenn Sie möchten, dass mehrere Komponenten über eine einzelne Änderung benachrichtigt werden, empfiehlt sich ein Observable oder ein Subject in einem gemeinsam genutzten Service. –