2016-06-07 4 views
34

In eckigen Dokumenten gibt es ein Thema über das Abhören von Kindereignissen von Eltern. Das ist gut. Aber meine Absicht ist etwas umgekehrt! In meiner App gibt es eine 'admin.component', die die Layout-Ansicht der Admin-Seite enthält (Sidebar-Menü, Taskleiste, Status usw.). In dieser übergeordneten Komponente konfigurierte ich das Router-System zum Ändern der Hauptansicht zwischen anderen Seiten des Administrators. Das Problem besteht darin, Dinge nach der Änderung zu speichern. Der Benutzer klickt auf die Schaltfläche Speichern in der Taskleiste (die in admin.component abgelegt ist), und die untergeordnete Komponente muss dieses Klickereignis abhören, um die Mitarbeiter zu retten.Kind hört Elternereignis in Angular 2

+2

klingt wie die beste Praxis dafür ist mit einem Service und einer beobachtbaren Dispatching der Veranstaltung. – zpul

+0

Ihre Frage ist nicht zu unähnlich von diesem: http://stackoverflow.com/questions/35560860/in-angular2-how-to-let-child-component-communicate-with-each-other – freethebees

+0

@freethebees Vielleicht die Lösung ist die gleiche, aber die Form des Problems ist anders und meine Absicht ist es, den besten Ansatz für diese Situation zu finden. –

Antwort

52

Ich denke, dass dieses Dokument für Sie hilfreich sein könnten:

In der Tat könnte man eine beobachtbare/Thema nutzen, dass die Eltern ihre Kinder zur Verfügung stellt. So etwas Ähnliches:

@Component({ 
    (...) 
    template: ` 
    <child [parentSubject]="parentSubject"></child> 
    `, 
    directives: [ ChildComponent ] 
}) 
export class ParentComponent { 
    parentSubject:Subject<any> = new Subject(); 

    notifyChildren() { 
    this.parentSubject.next('some value'); 
    } 
} 

Das Kind Komponente einfach zu diesem Thema abonnieren:

@Component({ 
    (...) 
}) 
export class ChildComponent { 
    @Input() 
    parentSubject:Subject<any>; 

    ngOnInit() { 
    this.parentSubject.subscribe(event => { 
     // called when the notifyChildren method is 
     // called in the parent component 
    }); 
    } 

    ngOnDestroy() { 
    // needed if child gets re-created (eg on some model changes) 
    // note that subsequent subscriptions on the same subject will fail 
    // so the parent has to re-create parentSubject on changes 
    this.parentSubject.unsubscribe(); 
    } 

} 

Andernfalls könnten Sie einen Shared-Service nutzen, ein solches Thema in ähnlicher Weise enthält ...

+0

Der Rückruf in meiner untergeordneten Komponente wird nur ausgeführt, wenn die übergeordnete Komponente den nächsten Wert innerhalb von ngInit überträgt. Warum ist das der Fall? – cjsimon

+2

Gibt es irgendwelche Vorteile der Verwendung dieser Methode gegenüber ViewChild? – sunnyiitkgp

+0

Obwohl es professioneller aussieht, nachdem ich einige Stunden damit verbracht habe, in meiner Situation zu experimentieren, konnte ich mit dem Abmelden von Fehlern beim Hinzufügen/Entfernen von untergeordneten Elementen (und damit dem Abmelden vom Thema) keine Probleme bekommen. Mit TimeBoxing habe ich mich für die viel einfachere Antwort von @StephenPaul entschieden. Trotzdem vielen Dank für die Antwort und wahrscheinlich bekomme ich die rxjs-Bibliothek gerade jetzt nicht gut genug, um sie vollständig zu verstehen und die richtigen (zusätzlichen) Anpassungen an Ihrem Beispiel vorzunehmen, damit es einwandfrei funktioniert. –

52

Aus Gründen der Nachwelt, nur gedacht, ich würde die konventionellere Lösung zu diesem erwähnen: Einfach einen Verweis auf das ViewChild erhalten und die Methode direkt aufrufen.

+27

Ich habe 2 Dinge aus Ihrer Antwort gelernt - Wie bekomme ich einen Verweis auf eine Kindkomponente und die Bedeutung des Wortes * nach * –

+1

Es stürzt ab, sobald ich die Elternkomponente eingeben ... 'Kann die Eigenschaft 'notifyMe' von nicht lesen undefiniert. –

+0

Hm, anscheinend wird Ihre Kindkomponente nicht von Angular gesetzt. Stellen Sie sicher, dass ChildComponent über den richtigen Selektor verfügt. –

1

Hier könnte ein eher blanker Ansatz möglich sein, wenn ich die Frage richtig verstehe. Annahmen -

  • OP hat eine Schaltfläche Speichern in der übergeordneten Komponente
  • Die Daten, die gespeichert werden muss, ist in den untergeordneten Komponenten
  • Alle anderen Daten, dass die untergeordnete Komponente muss möglicherweise von Services zugegriffen werden kann

in der übergeordneten Komponente

<button type="button" (click)="prop1=!prop1">Save Button</button> 
<app-child-component [setProp]='prop1'></app-child-component> 

Und in dem Kind ..

prop1:boolean; 
    @Input() 
    set setProp(p: boolean) { 
    // -- perform save function here 
} 

Dies sendet einfach den Button klicken auf die untergeordnete Komponente. Von dort kann die Kindkomponente die Daten unabhängig speichern.

BEARBEITEN: Wenn die Daten aus der Elternvorlage auch zusammen mit dem Knopfklick übergeben werden müssen, ist dies auch mit diesem Ansatz möglich. Lassen Sie mich wissen, ob das der Fall ist, und ich werde die Codebeispiele aktualisieren.