2017-02-16 4 views
2

app.component.ts является точкой входа моего приложения Angular 2. Он содержит два компонента: заголовок и sidenav.Как общаться между двумя компонентами без отношения родитель-ребенок?

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

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

Вот что я хочу добиться: Внутри <app-header> компонента У меня есть кнопка (меню), которое должно вызвать открытие <app-sidenav> компонента.

Другими словами, событие click на кнопке в <app-header> должно инициировать метод open() внутри компонента <app-sidenav>.

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

Я прочитал component interaction section в угловом 2 Docs , но я изо всех сил пытаюсь найти лучший подход к общению между этими двумя компонентами. Общее намерение заключается в том, чтобы инкапсулировать как можно больше логики для каждого компонента.

Как бы вы приблизились к моему брэнду? Создать промежуточную службу? Пожалуйста, поделитесь примером.

+3

https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service (не спрашивайте, почему в заголовке указано «Передача родителей и детей». для связи компонентов, независимо от того, как они связаны или не связаны. –

ответ

3

Вы можете использовать сервис, позволяющий двум отдельным компонентам разговаривать друг с другом. В приведенном ниже примере HeaderComponent подталкивает значение к экспонированному Observable с использованием метода toggleSideNav для SidebarService. SidenavComponent подписывается на этот Observable на его начальной нагрузке и будет реагировать на новое значение, которое проталкивается.

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

Т SidebarService необходимо зарегистрировать в подходящем модуле (например, ваш AppModule).

+0

Отлично, спасибо @Seaal! –

+2

Примечание: импортируйте «rxjs/Rx» с капиталом «R» в 'SidebarService'. В противном случае это вызвало ошибку при запуске angular-cli 1.0.0-beta.31 на узле 7.6 –

+0

В этом случае, как я могу уловить момент, когда вы нажимаете за пределами боковой панели и закрываете боковую панель? –

Смежные вопросы