2016-08-01 139 views
2

我有一個「appService」,我用它來處理我所有組件(窗體,導航等)之間的交互。angular2銷燬視圖銷燬訂閱

我的服務有許多事件發射器,組件訂閱(結果顯示,元素選擇,表單發佈等等)。

當顯示新視圖時,它會訂閱它需要的appService事件。現在的問題是,當我導航到另一個視圖(表單),不再需要的視圖被銷燬,但它的訂閱仍然被稱爲...!我發現引用了所有的訂閱,並且明確地取消訂閱了一個用於簡單任務的大型樣板。我究竟做錯了什麼?如何消化這個?

示例代碼:

export class VendorsForm { 
    constructor(private appService: AppServiceMain) 
    { 
      this.appService.onSearchResultSelected$.subscribe((selectedEntity) => { 
      //detailed view of this item 
      this.model = selectedEntity; 
      this.appService.setFormIsShowingDetail(); 
     }) 
    }); 

    } 
} 
現在

在另一個組件:

export class CustomersForm { 
    constructor(private appService: AppServiceMain) 
    { 
      this.appService.onSearchResultSelected$.subscribe((selectedEntity) => { 
      //detailed view of this item 
      this.model = selectedEntity; this.appService.setFormIsShowingDetail(); 
     }) 
    }); 

    } 
} 

只是作爲參考,這裏的服務和事件調用組件:

export class AppServiceMain { 
    public onSearchResultSelected$: EventEmitter<IEntity>; 
     setSelectedEntity(ent: IEntity) 
     { 
      this.formstate = states.EntitySelected; 
      this.onSearchResultSelected$.emit(ent); 
     } 

事件調用組件

export class ResultsComponent { 
    rowDblClick(ev$) 
    { 
     this.appService.setSelectedEntity(ev$.data); 
    } 

我明白如何刪除這些suscriptions,如果我想。問題是我的窗體非常大且功能強大,我有大量的非標準引用,Isnt有一種方法可以在視圖被破壞時自動停止監聽嗎?我發現手動銷燬所有這些很容易出錯。

+0

小評論:我的結果組件和appService都是活着的,並且是單實例 – user5328504

+0

你能否清楚爲什麼實現'ngOnDestroy'方法不適合你?如果你錯過了:[OnDestroy](https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html) – leovrf

回答

3

如果你訂閱勢在必行,那麼還取消勢在必行

this.someSubscription = this.appService.onSearchResultSelected$.subscribe((selectedEntity) => 

ngOnDestroy() { 
    this.someSubscription.unsubscribe(); 
} 

how to unsubscribe several subscriber in angular 2

+2

謝謝Günter,其實這就是我現在正在做的事情....我得到一個數組中的所有訂閱的句柄..但我討厭這樣做...我也看到有一種方法可以用「異步管道」自動化它,但也很糟糕...我覺得像angular2正在推動最怪異的模式...你怎麼處理這個東西?也許這種方法對於應用程序流管理沒有好處? – user5328504

+0

我沒有看到'|的問題異步「,也不退訂。 –

+0

我會將你的標記標記爲答案 - 只是說這個語法是CODE SMELL – user5328504

4

發現你並不需要有一堆訂閱。使用RxJS.SubjecttakeUntil組合來處理訂閱像一個老闆:

import {Subject} from "rxjs/Subject"; 

@Component(
    { 
     moduleId: __moduleName, 
     selector: 'my-view', 
     templateUrl: '../views/view-route.view.html', 
    } 
) 
export class ViewRouteComponent implements OnDestroy 
{ 
    componentDestroyed$: Subject<boolean> = new Subject(); 

    constructor(protected titleService: TitleService) 
    { 
     this.titleService.emitter1$ 
      .takeUntil(this.componentDestroyed$) 
      .subscribe(
      (data: any) => 
      { 
       // ... do something 1 
      } 
     ); 

     this.titleService.emitter2$ 
      .takeUntil(this.componentDestroyed$) 
      .subscribe(
      (data: any) => 
      { 
       // ... do something 2 
      } 
     ); 

     // ... 

     this.titleService.emitterN$ 
      .takeUntil(this.componentDestroyed$) 
      .subscribe(
      (data: any) => 
      { 
       // ... do something N 
      } 
     ); 
    } 

    ngOnDestroy() 
    { 
     this.componentDestroyed$.next(true); 
     this.componentDestroyed$.complete(); 
    } 
} 
+0

這是好東西 – user5328504

0

我這樣做的方式是:

this.subscriptions.push(this.appService.onSearchResultSelected$.subscribe((selectedEntity) => {})); 

ngOnDestroy() { 
    this.subscriptions.forEach((subscription) => { 
     subscription.unsubscribe(); 
    }); 
} 

您可以處理使用這種方式的訂閱數n,你只需要推每次使用訂閱。

這是最簡單和最簡單的方式來執行。