如何知道组件当前是否是路由器插座中的已加载组件

时间:2016-11-06 08:03:56

标签: angular angular2-routing eventemitter

我有一个延迟加载模块的应用程序。

在一个特定的延迟加载模块中,我有一个父组件,它有router-outlet

在该父组件中,我有一个按钮,它基本上使用共享服务(在延迟加载的模块上提供)发出事件。

每个子组件(在router-outlet中加载)都使用相同的共享服务订阅该事件!

我尝试使用 heroes demo 在以下plunkr中重新创建我的用例。

打开开发工具以查看console条消息。

  • 点击Heroes链接(默认情况下应该选中)。
  • 点击列表中的英雄物品。
  • 点击Admin链接。
  • 点击Emit Test按钮(右上导航)

你会在控制台看到 - 两个组件都收到了Event,即使两个组件都不应该是“活动”!!!

1)这是设计吗?

2)如何知道当前组件是否为活动组件?

内容/ UPDATE

根据我的理解,EventEmitter / Subject可以多次订阅,但是当取消订阅时你不能使用它/订阅它AFAIK。

我的解决方案是:

1)在服务中我结束了下面的事情:

get(){
  if (!this.testEvent.closed) {
      this.testEvent.complete();
      this.testEvent.unsubscribe();
    }
    this.testEvent= new EventEmitter<void>();
    return this.testEvent;
  }
}

2)在我订阅活动的每个组件中,我添加了ngDestroy并取消订阅了该活动:

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

2 个答案:

答案 0 :(得分:1)

您有一项服务,这是一个单身人士。该服务从应用程序的开始到结束都存在。

你有两个组成部分。这些不是单身人士。当它们必须显示在页面上时会被创建,并且当它们不再存在时会被销毁。

并且,在创建组件时,您在单例服务中订阅了一个observable。这是什么意思?这意味着observable需要保持对您的观察者的引用,观察者本身对组件实例具有一个重复引用(this)。如果没有该引用,则在发出事件时,observable将无法调用观察者。因此,即使Angular不再需要您的组件实例,observable仍然会引用它,并在发出事件时调用它。

因此,您需要在不再需要该组件时取消订阅:

private subscription: Subscription;

ngOnInit() {
    this.subscription = this.service.getTestEvent().subscribe(...);
}

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

如果不这样做,你不仅会让观察者一无所获,使应用程序变慢,而且还会出现内存泄漏。

答案 1 :(得分:1)

重点是您永远不会取消订阅该活动。 您点击用户的次数越多,您在控制台中看到的行就越多。 只要您单击订阅该事件,即添加一个将在事件被引发时执行的回调,除非您取消订阅。 在方法ngOnDestroy()中,您应该在订阅上调用unsubscribe()方法(这是subscribe()方法返回的对象)。

换句话说就像这样

subscrition: Subscription;

ngOnInit() {

    this.subscription = this.service.getTestEvent().subscribe( (e) => {
      console.log('HeroListComponent ==>');
    });

.....

}

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

我希望这会有所帮助。