2017-02-16 4 views
2

Die app.component.ts ist der Einstiegspunkt meiner Angular 2 App. Es enthält zwei Komponenten: eine Kopfzeile und eine sidenav.Wie kommuniziert man zwischen zwei Komponenten ohne Eltern-Kind-Beziehung?

@Component({ 
    selector: 'app-root', 
    template: ` 
    <app-header></app-header> 

    <app-sidenav></app-sidenav> 
    ` 
}) 
export class AppComponent { } 

Hier ist, was ich erreichen möchte: In der <app-header> Komponente Ich habe eine (Menü) Taste, die die Öffnung des <app-sidenav> Komponente auslösen soll.

Mit anderen Worten, ein Klickereignis auf der Schaltfläche in der <app-header> sollte die open() Methode innerhalb der <app-sidenav> Komponente auslösen.

  • header.component.ts:

    @Component({ 
        selector: 'app-header', 
        template: ` 
        <button (click)="onSidenavOpen()">Menu</button> 
        ` 
    }) 
    export class HeaderComponent { 
        constructor() { } 
    
        onSidenavOpen() { 
        // trigger the opening of the <app-sidenav> component 
        } 
    } 
    
  • sidebar.component.ts:

    @Component({ 
        selector: 'app-sidenav', 
        template: ` 
        <md-sidenav #sidenav> 
         // bla bla, sidebar 
        </md-sidenav> 
        ` 
    }) 
    export class SidenavComponent { 
        constructor() { } 
    
        open(sidenav) { 
        sidenav.open(); 
        } 
        close(sidenav) { 
        sidenav.close(); 
        } 
    } 
    

las ich die component interaction section in den Angular 2 docs , aber ich habe Mühe zu finden der beste Ansatz, um zwischen diesen beiden Komponenten zu kommunizieren. Die allgemeine Absicht, die ich habe, ist es, so viel Logik wie möglich für jede Komponente einzukapseln.

Wie würden Sie meinen Anwendungsfall angehen? Würden Sie einen Zwischenservice erstellen? Bitte teilen Sie ein Beispiel.

+3

https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service (fragen Sie nicht, warum die Überschrift "Eltern- und Kinderkommunikation" lautet. Die Verwendung eines Dienstes ist für Komponentenkommunikation, egal wie sie sind oder nicht verwandt sind –

Antwort

3

Sie können einen Dienst verwenden, damit zwei separate Komponenten miteinander kommunizieren können. Im folgenden Beispiel drückt der Wert HeaderComponent einen Wert auf eine exponierte Observable mit der toggleSideNav Methode der SidebarService. Die SidenavComponent abonniert diese Observable bei ihrer anfänglichen Belastung und reagiert auf einen neuen Wert, der durchgeschaltet wird.

SidebarService:

import { Injectable } from "@angular/core" 

import { Observable, Subject } from "rxjs/Rx"; 

@Injectable() 
export class SidebarService { 

    private sidenavOpenSubject : Subject<boolean>; 

    constructor() { 
     this.sidenavOpenSubject = new Subject<boolean>(); 
    } 

    toggleSideNav(opening: boolean): void { 
     this.sidenavOpenSubject.next(opening); 
    } 

    onSideNavToggle(): Observable<boolean> { 
     return this.sidenavOpenSubject; 
    } 

} 

HeaderComponent:

@Component({ 
    selector: 'app-header', 
    template: ` 
    <button (click)="onSidenavOpen()">Menu</button> 
    ` 
}) 
export class HeaderComponent { 
    constructor(private sidebarService: SidebarService) { } 

    onSidenavOpen() { 
    this.sidebarService.toggleSideNav(true); 
    } 
} 

SidebarComponent:

@Component({ 
    selector: 'app-sidenav', 
    template: ` 
    <md-sidenav #sidenav> 
     // bla bla, sidebar 
    </md-sidenav> 
    ` 
}) 
export class SidenavComponent implements OnInit { 
    constructor(private sidebarService: SidebarService) { } 

    ngOnInit(): void { 
     this.sidebarService.onSideNavToggle().subscribe(
      (opening) => { 
       if (opening) { 
        //Logic to open the sidenav here 
       } else { 
        //Logic to close the sidenav here 
       } 
      } 
     ); 
    } 

    open(sidenav) { 
     sidenav.open(); 
    } 

    close(sidenav) { 
     sidenav.close(); 
    } 
} 

T er SidebarService muss in einem geeigneten Modul (z.B. Ihre AppModule).

+0

Großartig, danke @Seaal! –

+2

Hinweis: importieren Sie "Rxjs/Rx" mit Kapital "R" in der 'SidebarService', sonst verursachte es mir einen Fehler ausgeführt angular-cli 1.0.0-beta.31 am Knoten 7.6 –

+0

In diesem Fall, wie kann ich den Moment erfassen, wenn Sie außerhalb der Sidebar klicken und die Sidebar schließen? –

Verwandte Themen