Angular2,取消了ngOnDestroy

时间:2016-01-21 14:37:44

标签: angular eventemitter

在我的应用程序中,我有一些通过EventService进行通信的组件。

@Injectable()
export class EventService {
  public myEvent: EventEmitter<any> = new EventEmitter();
  constructor() {}
}

此服务注入EmitterComponent,点击按钮时会发出事件

@Component({
  selector: 'emitter',
  template: `<button (click)="onClick()">Click me</button>`,
})
export class EmitterComponent {
  constructor(private eventService:EventService) {}
  onClick() {
    this.eventService.myEvent.emit();
  }
}

并且在订阅该事件的ReceiverComponent中,对于收到的每个事件递增一个计数器

@Component({
  selector: 'receiver',
  template: `Count: {{count}}`,
})
export class ReceiverComponent {
  public count = 0;
  constructor(private eventService:EventService) {
    this.eventService.myEvent.subscribe(() => this.count++;);
  }
}

该应用程序有多个视图(在此示例中只有两个):PageAPageBEmitterComponentReceiverComponent位于PageA。每次我转到PageB并返回PageA,都会创建一个新的ReceiverComponent,当我点击EmitterComponent中的按钮时,{{1}的事件回调函数多次执行。

为避免这种情况,我在ReceiverComponent

中取消订阅ReceiverComponent中的myEvent
ngOnDestroy

但这会导致以下异常

ngOnDestroy() {
  this.eventService.myEvent.unsubscribe();
}

我该如何避免?如何正确取消订阅?

为了更好地理解,我创建了这个plunker,您可以在控制台中看到错误和一些注释。

2 个答案:

答案 0 :(得分:33)

您从.subscribe()获得订阅。使用其unsubscribe()方法取消订阅。

@Component({
  selector: 'receiver',
  template: `Count: {{count}}`,
})
export class ReceiverComponent {
  public count = 0;
  private subscription;
  constructor(private eventService:EventService) {
    this.subscription = this.eventService.myEvent.subscribe(() => this.count++;);
  }
  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

另见

答案 1 :(得分:2)

我认为你应该取消订阅,如下所述:

export class ReceiverComponent {
  public count = 0;
  private id;

  constructor(private eventService:EventService) {
    this.id = Date.now();
    console.log("ReceiverComponent constructor " + this.id);
    this.subscription = this.eventService.myEvent.subscribe(() => {
      console.log("count " + this.count + " (id ReceiverComponent instance: " + this.id + ")");
      this.count++;
    });
  }

  ngOnDestroy() {
    console.log("onDestroy of ReceiverComponent " + this.id)
    //this cause "Cannot subscribe to a disposed Subject."
    //this.eventService.myEvent.unsubscribe();
    this.subscription.unsubscribe();
  }
}

实际上,EventEmitter是共享的可观察对象,即热可观察对象。以下是您可能感兴趣的链接:https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/creating.md

希望它可以帮到你, 亨利