Angular2,取消订阅 ngOnDestroy 中的事件
Angular2, unsubsribe from event in ngOnDestroy
在我的应用程序中,我有一些组件通过 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
中的按钮时,[=17]的事件回调函数=]被执行了几次。
为了避免这种情况,我在 ngOnDestroy
中从 myEvent
退订了 ReceiverComponent
ngOnDestroy() {
this.eventService.myEvent.unsubscribe();
}
但这会导致以下异常
EXCEPTION: Error during instantiation of ReceiverComponent!.
ORIGINAL EXCEPTION: Error: Cannot subscribe to a disposed Subject
我怎样才能避免这种情况?如何正确退订?
为了更好地理解,我创建了这个 plunker,您可以在控制台中看到错误和一些注释。
您从 .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();
}
}
另见
我认为您应该取消订阅,如下所述:
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
s 是共享的可观察对象,即热可观察对象。这是您可能感兴趣的 link:https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/creating.md.
希望对你有帮助,
蒂埃里
在我的应用程序中,我有一些组件通过 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
中的按钮时,[=17]的事件回调函数=]被执行了几次。
为了避免这种情况,我在 ngOnDestroy
myEvent
退订了 ReceiverComponent
ngOnDestroy() {
this.eventService.myEvent.unsubscribe();
}
但这会导致以下异常
EXCEPTION: Error during instantiation of ReceiverComponent!.
ORIGINAL EXCEPTION: Error: Cannot subscribe to a disposed Subject
我怎样才能避免这种情况?如何正确退订?
为了更好地理解,我创建了这个 plunker,您可以在控制台中看到错误和一些注释。
您从 .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();
}
}
另见
我认为您应该取消订阅,如下所述:
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
s 是共享的可观察对象,即热可观察对象。这是您可能感兴趣的 link:https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/creating.md.
希望对你有帮助, 蒂埃里