This solution allows you to directly write parameters in a function call instead of having to wrap all your parameters in an object.
interface ISubscription { (...args: any[]): void; } class PubSub<T extends ISubscription> { protected _subscribed : ISubscriptionItem[] = []; protected findSubscription(event : T) : ISubscriptionItem { this._subscribed.forEach( (item : ISubscriptionItem) =>{ if (item.func==event) return item; } ); return null; } public sub(applyObject : any,event : T) { var newItem = this.findSubscription(event); if (!newItem) { newItem = {object : applyObject, func : event }; this._subscribed.push(newItem); this.doChangedEvent(); } } public unsub(event : T) { for ( var i=this._subscribed.length-1 ; i>=0; i--) { if (this._subscribed[i].func==event) this._subscribed.splice(i,1); } this.doChangedEvent(); } protected doPub(...args: any[]) { this._subscribed.forEach((item : ISubscriptionItem)=> { item.func.apply(item.object, args); }) } public get pub() : T { var pubsub=this; var func= (...args: any[]) => { pubsub.doPub(args); } return <T>func; } public get pubAsync() : T { var pubsub=this; var func = (...args: any[]) => { setTimeout( () => { pubsub.doPub(args); }); } return <T>func; } public get count() : number { return this._subscribed.length } }
Using:
interface ITestEvent { (test : string): void; } var onTestEvent = new PubSub<ITestEvent>(); //subscribe to the event onTestEvent.sub(monitor,(test : string) => {alert("called:"+test)});
user2866593 Aug 17 '15 at 15:15 2015-08-17 15:15
source share