2016-09-25 105 views
2

我是Angular 2和RXJS的新手。我有一個帶有2個觸發器(按鈕)的自定義頭部組件,它應該在應用程序的不同部分激活2個不同的導航指令。我創建了一個服務,它註冊了2個不同的導航指令,並且標頭組件訂閱了這個。我想知道什麼是鏈接標題中按鈕的最佳方法,以根據點擊的觸發器調用每個指令中的open()和close()函數。Angular 2 Service + RxJS BehaviorSubject或EventEmitter

注意:請注意,我無法使用ViewChild或ContentChild,因爲導航可以位於頁面上的任何位置。它們可以位於不同的CustomComponent中,不一定是標頭組件的子項。

我能想到的2種選擇:

  1. 創建在服務中2個導航指令,2個獨立的觀測量/ BehaviorSubjects,讓頭通過打開和關閉的消息給他們,並有單獨的導航指令訂閱給每個相應的觀察者。
  2. 使用EventEmitters,但我不知道如何使用這種方法。

請問您能否提出解決此問題的好方法?含導航

定製組件:

@Component({ 
    selector: 'my-app', 

    template: ` 
    <h1>{{title}}</h1> 
    <my-custom-header> 
     This is some text inside the header 
    </my-custom-header> 
    <nav custom-nav-1>Custom Nav 1</nav> 
    <nav custom-nav-2>Custom Nav 2</nav> 
    ` 
}) 
export class AppComponent { 
    title = 'Hello!'; 
} 

標題組件:

@Component({ 
    selector: 'my-custom-header', 

    template: ` 
    <div class="container"> 
     This is a header 
     <ng-content></ng-content> 
     <div>Number of Nav Registered: {{noOfNav}}</div> 
     <button type="button" (click)="toggleNav1()">Toggle Nav 1</button> 
     <button type="button" (click)="toggleNav2()">Toggle Nav 2</button> 
    </div> 
    `, 
    styles: ['.container { border: 1px solid; }'], 
}) 
export class HeaderComponent { 
    title = 'Hello!'; 
    noOfNav = 0; 

    constructor(private navService: NavService) {} 

    ngOnInit() { 
    this.navService._navSubject.subscribe({ 
     next: (id) => { 
     if(id!=0) { 
      this.noOfNav++; 
     } 
     } 
    }); 
    } 

    toggleNav1() { 
    console.log("Toggle Nav 1"); 
    } 

    toggleNav2() { 
    console.log("Toggle Nav 2"); 
    } 
} 

NavService:

@Injectable() 
export class NavService { 
    public _navSubject: BehaviodSubject = new BehaviorSubject<number>(0); 

    registerNavId(id: number) { 
    this._navSubject.next(id); 
    } 
} 

Nav1Directive

@Directive({ 
    selector: '[custom-nav-1]' 
}) 
export class NavDirective1 { 
    constructor(private navService: NavService) {} 

    ngOnInit() { 
    this.navService.registerNavId(1); 
    } 

    isOpen() { 
    console.log("isOpen"); 
    } 

    open() { 
    console.log("Open Nav"); 
    } 

    close() { 
    console.log("Close Nav"); 
    } 
} 

Nav2Directive:

@Directive({ 
    selector: '[custom-nav-2]' 
}) 
export class NavDirective2 { 
    constructor(private navService: NavService) {} 

    ngOnInit() { 
    this.navService.registerNavId(2); 
    } 

    isOpen() { 
    console.log("isOpen"); 
    } 

    open() { 
    console.log("Open Nav 2"); 
    } 

    close() { 
    console.log("Close Nav 2"); 
    } 
} 

Plunker:https://plnkr.co/edit/3ISyH7ESoNlt65J56Yni?p=preview

+0

那麼問題是什麼? – micronyks

+0

我想知道最好的方法來解決這個問題。 Observable方式,EventEmitter方式還是其他方法? – takeradi

+0

它按預期工作嗎?我點擊兩個按鈕時看不到任何東西。 – micronyks

回答

0

由於你的組件是鬆耦合的(不知道對方),你需要它們之間的相互作用,你的方法(使用RxJS)是大多數對應於angular2的方法。

現在一切都變得活躍,甚至形式。

當您從可重用組件輸出事件時,EventEmitter很好,而且很簡單。