observables example angular eventemitter

example - unsubscribe observable angular 4



Angular2, anular la suscripciĆ³n del evento en ngOnDestroy (2)

Esta pregunta ya tiene una respuesta aquí:

En mi aplicación tengo algunos componentes que se comunican mediante EventService .

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

Este servicio se inyecta en un EmitterComponent que emite el evento cuando se hace clic en un botón

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

y en un ReceiverComponent que se suscribe al evento y por cada evento recibido aumenta un contador

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

La aplicación tiene múltiples vistas (en este ejemplo solo dos): PageA y PageB . EmitterComponent y ReceiverComponent están en PageA . Cada vez que voy a PageB y vuelvo a PageA , se PageA un nuevo ReceiverComponent y cuando hago clic en el botón en EmitterComponent , la función de devolución de llamada de evento de ReceiverComponent se ejecuta varias veces.

Para evitar esto, doy de baja ReceiverComponent de myEvent en ngOnDestroy

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

pero esto provoca la siguiente excepción

EXCEPTION: Error during instantiation of ReceiverComponent!. ORIGINAL EXCEPTION: Error: Cannot subscribe to a disposed Subject

¿Cómo puedo evitar eso? ¿Cómo darse de baja correctamente?

Para una mejor comprensión, he creado este plunker donde puede ver el error y algunos comentarios en la consola.


Creo que deberías cancelar la suscripción, como se describe a continuación:

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(); } }

De hecho, los EventEmitter son observables compartidos, es decir, observables en caliente. Aquí hay un enlace que podría interesarle: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/creating.md .

Espero te ayude, Thierry


.subscribe() una suscripción de .subscribe() . Use su método para unsubscribe() para cancelar la suscripción.

@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(); } }

Ver también