2016-08-01 137 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,你只需要推每次使用订阅。

这是最简单和最简单的方式来执行。