typescript - Pub-Sub-implementation för Angular 5-applikation
Har letat efter något liknande IEventAggregator i WPF-Prism-ramverket.
Det här är något av samma fråga i mitt huvud, förutom att jag letar efter en lösning i Angular 5.
Har inte kunnat hitta en enkel lösning hittills. Fick skapa en själv med hjälp av TypeScript-generics, Angular dependency injection med tjänster och "rxjs/Subject".
Det är mest inspirerat av detta inlägg.
En tjänst som heter EventService skapas och registreras som ett beroende i AppModule. Eftersom den är tillagd i NgModule.providers-listan i AppModule kan den lösas som ett beroende i vilken komponent som helst.
EventService :
/**
* For inter component communication throughout application.
* Use dependency injection to raise an event with payload.
* NOTE: All subscriptions to be unsubscribed at ngOnDestroy() method of subscribing component
*/
@Injectable()
export class EventService {
private someDataChangeEvent: IEvent<string> = new Event<string>();
constructor() { }
public get someDataChange(): IEvent<string> {
return this.userImageChangeEvent;
}
}
där IEvent och Event är:
import { Subscription } from "rxjs";
import { Subject } from "rxjs/Subject";
export interface IEvent<T> {
/**
* Method which will signal the subscribers.
* @param payload
*/
publish(payload: T): void,
/**
* Registers the payload receiving function.
* NOTE: Subscribing component should handle the subscription disposal on ngOnDestroy method.
* @param callback: callback function
*/
subscribe(callback: (payload: T) => void): Subscription
}
export class Event<T> implements IEvent<T> {
private subject = new Subject<any>();
constructor() { }
public publish(payload: T): void {
// Notify subscribers.
this.subject.next(payload);
}
public subscribe(callback: (payload: T) => void): Subscription {
// Create a subscription with the passed callback
let subscription = this.subject.asObservable().subscribe(callback);
return subscription;
}
}
Vid publiceringskomponenten
1. Konstruktor - lös beroende:
constructor(
private readonly _eventService: EventService
) { }
Publicera händelsen när datan ändras. Säg, httpClient är färdig med hämtning eller ändring av ett rullgardinsobjekt eller ett knapptryck.
payloadär datan du skickar till den prenumererande komponenten.self._eventService.someDataChange.publish(payload);
Nu, vid den prenumererande komponenten
- Implementera OnInit och OnDestroy
- Konstruktör - lös beroendet, samma som ovan
- I ngOnInit-metoden, prenumerera på händelsen
I ngOnDestroy avregistrera prenumeration.
export class SomeComponent implements OnInit, OnDestroy { constructor( private readonly _eventService: EventService ) { } private eventSubscription: Subscription = null; ngOnInit() { this.eventSubscription = this._eventService.someDataChange.subscribe((payload) => { // Do something with payload }); } ngOnDestroy() { this.eventSubscription.unsubscribe(); } }
Jag kan definiera så många olika händelser som applikationen behöver och flera komponenter kan prenumerera på dessa händelser. Men alla dessa prenumerationer måste jag noggrant ta bort i ngOnDestroy-metoden.
Finns det ett sätt att undvika det? Finns det ett sätt att automatiskt ta bort prenumerationen när komponenten förstörs utan att göra det uttryckligen.
Med ett eller två händelser över applikationen fungerar detta bra. Men med mer än 10 händelser registrerade i EventService, och flera komponenter som prenumererar på de flesta händelser, tvivlar jag på om detta är en bra lösning?
Vilka är mina alternativ? Som minst skulle en automatisk avregistrering för borttagna komponenter vara till stor hjälp. Tack.