在我的应用程序中,我有一些通过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++;);
}
}
该应用程序有多个视图(在此示例中只有两个):PageA
和PageB
。 EmitterComponent
和ReceiverComponent
位于PageA
。每次我转到PageB
并返回PageA
,都会创建一个新的ReceiverComponent
,当我点击EmitterComponent
中的按钮时,{{1}的事件回调函数多次执行。
为避免这种情况,我在ReceiverComponent
ReceiverComponent
中的myEvent
ngOnDestroy
但这会导致以下异常
ngOnDestroy() {
this.eventService.myEvent.unsubscribe();
}
我该如何避免?如何正确取消订阅?
为了更好地理解,我创建了这个plunker,您可以在控制台中看到错误和一些注释。
答案 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。
希望它可以帮到你, 亨利