2017-02-16 2 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> 구성 요소의 개방을 트리거해야 (메뉴) 버튼을 가지고있다.

즉, <app-header>에있는 버튼의 클릭 이벤트는 <app-sidenav> 구성 요소 내에 open() 메소드를 트리거해야합니다.

  • 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 읽기 ,하지만 나는 고심하고있다. 이 두 가지 구성 요소간에 의사 소통하는 가장 좋은 방법입니다. 내가 가진 일반적인 의도는 각 구성 요소에 가능한 한 많은 논리를 캡슐화하는 것입니다.

어떻게하면 유스 케이스에 접근 할 수 있습니까? 중간 서비스를 만들겠습니까? 예를 들려주십시오.

+3

https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service (캡션에 "부모와 자녀의 의사 소통"이 표시되는 이유를 묻지 마십시오.) 서비스 사용하기 구성 요소 통신의 경우 아무리 관련이 있거나 상관 관계 없음 –

답변

3

서비스를 사용하면 두 개의 개별 구성 요소가 서로 통신 할 수 있습니다. 아래 예에서 HeaderComponent은 의 toggleSideNav 방법으로 노출 된 Observable으로 값을 푸시합니다. 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(); 
    } 
} 

T 그는 SidebarService을 적절한 모듈에 등록해야합니다 (예 : 귀하의 AppModule).

+0

좋음, 감사합니다. –

+2

참고 : "SidebarService"에 "R"이있는 "rxjs/Rx"를 가져 오십시오. 그렇지 않으면 실행 오류가 발생합니다. 노드 7.6의 angular-cli 1.0.0-beta.31 –

+0

이 경우 사이드 바 외부를 클릭하거나 사이드 바를 닫을 때 어떻게 잡을 수 있습니까? –