@ortoo/angular-resource
Version:
Magical CRUD resource management for angular
108 lines (85 loc) • 2.74 kB
text/typescript
import { Subject } from 'rxjs/Subject';
import { Subscription } from 'rxjs/Subscription';
declare type SubscriptionArray = Subscription[];
export { Subscription } from 'rxjs/Subscription';
export interface Handler {
(...args: any[]): void;
}
export class EventEmitter {
private subjects: Map<string, Subject<any>>;
private subscriptions: Map<string, Map<Handler, SubscriptionArray>>;
constructor() {
this.subjects = new Map<string, Subject<any>>();
this.subscriptions = new Map<string, Map<Handler, SubscriptionArray>>();
}
public dispose() {
this.subjects.forEach((subject: Subject<any>) => {
subject.unsubscribe();
});
this.subjects.clear();
}
public addListener(name: string, handler: Handler) {
return this.on(name, handler);
}
public emit(fnName: string, ...data: any[]) {
let subject = this.getSubject(fnName);
subject.next(data);
}
public listen(name: string, handler: Handler): Subscription {
let subscription = this.getSubject(name).subscribe(handler);
this.registerSubscription(name, handler, subscription);
return subscription;
}
public off(name: string, handler: Handler) {
let subs = this.getSubscriptions(name, handler);
subs.forEach(sub => sub.unsubscribe());
}
public on(name: string, handler: Handler) {
let subscription = this.getSubject(name).subscribe(val => {
if (Array.isArray(val)) {
handler(...val);
} else {
handler(val);
}
});
this.registerSubscription(name, handler, subscription);
}
public once(name: string, handler: Handler) {
let onceHandler = (value: any) => {
this.off(name, onceHandler);
handler(value);
};
return this.on(name, onceHandler);
}
public removeListener(name: string, handler: Handler) {
return this.off(name, handler);
}
private registerSubscription(name: string, handler: Handler, sub: Subscription) {
let handlerMap = this.subscriptions.get(name);
if (!handlerMap) {
handlerMap = new Map<Handler, SubscriptionArray>();
this.subscriptions.set(name, handlerMap);
}
let subArr = handlerMap.get(handler);
if (!subArr) {
subArr = [];
handlerMap.set(handler, subArr);
}
subArr.push(sub);
}
private getSubscriptions(name: string, handler: Handler): SubscriptionArray {
let handlerMap = this.subscriptions.get(name);
if (!handlerMap) {
return [];
}
return handlerMap.get(handler) || [];
}
private getSubject(fnName: string): Subject<any> {
let subject = this.subjects.get(fnName);
if (!subject) {
subject = new Subject<any>();
this.subjects.set(fnName, subject);
}
return subject;
}
}