2017-05-30 60 views
1

我已經構建了一個名爲CoreButtonService的抽象類,每個ButtonService都將擴展它。例如,有UserButtonService,MessageButtonService等。這些服務將被注入到相應的組件,如UserComponent,MessageComponent等等。在CoreButtonService的構造函數中,我訂閱了另一個名爲ButtonsService的服務,該服務負責在ButtonModule中的任何按鈕被點擊時觸發事件。擴展類的構造函數中的訂閱無法正常工作

CoreButtonService:

export abstract class CoreButtonService<T extends CoreModel> extends CoreService { 

    private backSource = new Subject<string>(); 
    private submitSource = new Subject<string>(); 
    back$ = this.backSource.asObservable(); 
    submit$ = this.submitSource.asObservable(); 

    constructor(
     private coreButtonsService: ButtonsService, 
     private coreLanguageService: LanguageService, 
     private coreLocation: Location) { 
     super(coreLanguageService); 
     this.coreButtonsService 
      .buttonClicked$ 
      .subscribe(button => console.log(button)); // !!!!!! 
    } 

    // Buttons are going to be built down here ... 

} 

ButtonsService:

@Injectable() 
export class ButtonsService { 
    private button = new Subject<ButtonBase<any>>(); 
    buttonClicked$ = this.button.asObservable(); 
    constructor(private formService: FormService) { } 

    clickButton(button: ButtonBase<any>): void { 
     if (button.controlType === 'submit') 
      this.formService.submitForm(button.parent); 
     this.button.next(button); 
    } 
} 

假設我參觀,其中包括UserComponent頁面,點擊一個按鈕,然後做同樣的頁面上MessageComponent。從技術上講,應該在控制檯內記錄2個按鈕。 UserComponent的按鈕和我可以通過button.parent識別的MessageComponent的按鈕。但是我得到了MessageComponent的2個按鈕。

當我在CoreButtonService中保存發送的父項並將其記錄爲按鈕時,我得到期望的值:MessageComponent的'MessageForm'和UserComponent的'UserForm'。但button.parent的值都是一樣的。這怎麼可能?

我沒有看到問題。可能是因爲每個ButtonService都在CoreButtonService中執行相同的訂閱,這就是爲什麼每個訂閱/按鈕都相互關聯的原因?

UPDATE

這是plunkr的基本概念。

+0

在MessageComponent上單擊UserComponent,顯示Object {key:「back」,parent:「MessageForm」},測試並顯示「Object {key:」back「,parent:」UserForm「}。什麼出錯? – Val

+0

@Val這很奇怪。當我第一次點擊UserComponent上的「back」時,它會顯示Object {key:「back」,parent:「UserForm」}。當我導航到MessageComponent並單擊「返回」時,它顯示Object {key:「back」,parent:「MessageForm」} Object {key:「back」,parent:「MessageForm」}。所以它被記錄了兩次。 – user289520

+0

是否有像@Val一樣的日誌行爲的其他訪問者?如果是的話,在我的情況下會導致這種行爲? – user289520

回答

1

我終於找到了錯誤,這是一個非常愚蠢的。在CoreComponent中,我取消訂閱,如

ngOnDestroy() { 
    this.subscription.unsubscribe; 
} 

而不是unsubscribe()。所以這些事件有點瘋狂。但無論如何感謝您的幫助。

+0

很忙,很難用手機回覆。你的答案很好。 – Val

+0

'this.subscription.unsubscribe()'。 'this.subscription.unsubscribe'是一個noop。 – estus

0

爲了更詳細地解釋@ user289520的溶液:

  • Subscriptions:表示一個一次性資源,如可觀察的執行。訂閱有一個重要的方法,即unsubscribe,它不採用任何參數,只處理預訂所持有的資源。

您可以在ngOnDestroy()中立即收集想要unsubscribe的訂閱。

  • ngOnDestroy():在Angular破壞指令/組件之前進行清理。取消訂閱observables並分離事件處理程序以避免內存泄漏。

但是除了this.subscription.unsubscribe;你也可以做到這一點,如下所示foreach循環:

this.subscriptions.forEach(s => s.unsubscribe()); 

爲什麼你不能忘記unsubscribe()angular.js

  • 承諾是渴望並立即執行。觀察對象並不急切,只有在執行subscribed時纔會執行。
  • 承諾是asynchronous。可觀測量可以是synchronousasynchronous
  • 承諾預期只會返回一個值(如函數)。可觀測量可以返回零,一個或多個(無限)值。