📜 ⬆️ ⬇️

Building scalable applications in TypeScript. Part 2.5 - Bug Work and Delegates

Part 1: Asynchronous Module Loading
Part 2: Events or why you should reinvent your own bike

Unfortunately, the Moscow heat seriously affected my attentiveness at the time of writing the second part of the article, which led to one unpleasant mistake - the wrong typing of the parameters of the generalized class of events that this post is intended to correct.

But just to write a work on the bugs would not be interesting. Fortunately, the process of correcting it in itself threw a couple of interesting finds and thoughts that I would like to bring to the court of the community.
')
So, my WinAmp plays a collection of hits Ozzy Osbourne, and I ask everyone interested in a cat.

Mistake


In the second part of the article, the following code was published in the section “Typing of Event Parameters” (here is the full code from Codeplex ):

export class Event<Callback extends Function, Options> { private Callbacks: Callback[] = []; public Add(callback: Callback): ITypedSubscription<Callback, Event<Callback, Options>> { var that = this; var res: ITypedSubscription<Callback, Event<Callback, Options>> = { Callback: callback, Event: that, Unsubscribe: function () { that.Remove(callback); } } this.Callbacks.push(callback); return res; } public Remove(callback: Callback): void { var filteredList: Callback[] = []; for (var i = 0; i < this.Callbacks.length; i++) { //  .     if (this.Callbacks[i] !== callback) { filteredList.push(callback); } } this.Callbacks = filteredList; } public Trigger(options: Options): void { for (var i = 0; i < this.Callbacks.length; i++) { this.Callbacks[i](options); } } } 


The error was that in the signature of the Event class:

 Event<Callback extends Function, Options> 


there is no connection between its generalized parameters at the type level. In fact, it turns out that the first argument type is a Callback is some arbitrary function that does not have a specific signature, and the second argument type is a type of object that we then use to call the callbacks added to the event. Those. the parameters are not interconnected and in this implementation it is just elementary to shoot a leg without agreeing on these parameters, which an inexperienced developer most likely will not do.

And then street magic begins.

Delegates


Russian Wikipedia tells us that:

Delegate (English delegate) - a data structure that points to methods (static or class instance) in the .NET Framework. Delegates are used, in particular, to define a prototype callback function, for example, in the .NET Framework event model.

The English version additionally indicates that delegates are a type-safe function pointer, i.e. strongly typed reference to a function (translation and interpretation are free).

Depending on the context, a delegate can be understood as a type or a specific instance.

In simple words, closer to the world of JS, it is a strongly typed variable that stores a function of a strictly defined type. In other words, the delegate strictly defines the signature of the method.

In JS, delegates do not exist explicitly, because All functions are objects, and yes even dynamic typing. This means that JS supports delegates without any additional gestures.

An example of a delegate in TS would be the callback parameter from the following example:

 function Boo(callback: (strings: string[]) => string) { /*  */ } 


Here, we strictly typify the callback parameter as a method that accepts strictly one mandatory parameter of the type of an array of strings.

But such a record does not suit us, because we need a generic delegate that we could type based on the event declaration.

First, we must declare a delegate as a type in order to reuse it. To my great surprise, the TS 0.9 specification and the almighty Google could not help me in determining the syntax of such a structure. The answer was found on Codeplex in discussions on TS somewhere for the second hour of searches:

 export interface IDelegateTest { (options: any); } var test: IDelegateTest = function (options: any) { } 


With this entry, we declare that the IDelegateTest interface is a type of delegate that has a single parameter of type any. In this case, it is allowed to change the name of the parameters, but not their number and type. For example, the following code is completely correct:

 // var test: IDelegateTest = function (settings: any) { } 


Like this one:

 //  var test: IDelegateTest = function (options?: any) { } 


And even this one:

 //   ,     var test: IDelegateTest = function () { } 


Or this one:

 // !!! var test: IDelegateTest = function (options: number) { } 


“Stop!” The attentive reader will say. We change what we should not. Answer: options declared as any , which forgives everything. Honestly, I spent about 10 minutes until I understood the reason “in three pines”. I hope that no one else will fall into this trap.

But everything is correct:

 export interface IDelegateTest { //   (options: string); } // Cannot convert '(options: number) => void' to 'IDelegateTest' var test1: IDelegateTest = function (options: number) { } //Call signatures of types '(options?: number) => void' and 'IDelegateTest' are incompatible. var test2: IDelegateTest = function (options?: number) { } //   var test3: IDelegateTest = function (settings: string) { } 


Secondly, we will remake our delegate into a generalized one and give him the correct name. Everything is expected in terms of syntax and simple:

 export interface ICallback<ArgType> { (arg: ArgType, context?: any); } 


The options parameter is our typed parameter, and context allows us to specify the object that caused the event, which can be useful if the event is triggered by some third object and needs to be monitored. I’ll draw your attention to the fact that the context is not controlled from the subscriber in any way, unlike Backbone.Events, in which the context is set by the subscriber for the separation of similar handlers.

There is one implicit point in this code. If you declare context first, according to the traditions of C #: (object sender, EventArgs args) , then the TS compiler will not be able to track the correspondence of function types. I do not know what it is: a bug or a feature, but you should pay attention to it. If the typed parameters are at the beginning, then everything works predictably. What suits me completely in the context of the article.

Corrected Event


Add the following interface:

 export interface ICallbackDesc<ArgType> { Callback: ICallback<ArgType>; Subscriber: any; } 


ICallbackDesc we need to store information about the context in which the callback should be called. Those. we have to remember what value this should get in the callback, otherwise we just won't be able to work fully.

Adjust our Event class:

 export class Event<ArgType> { private Callbacks: ICallbackDesc<ArgType>[] = []; /**    * @param {ICallback<ArgType>} callback Callback,       * @param {any} subscriber ,      callback * @returns {ITypedSubscription<ArgType>}    */ public Subscribe(callback: ICallback<ArgType>, subscriber: any): ITypedSubscription<ArgType> { var that = this; var res: ITypedSubscription<ArgType> = { Callback: callback, Event: that, Unsubscribe: function () { that.Unsubscribe(callback); } } this.Callbacks.push({ Callback: callback, Subscriber: subscriber }); return res; } public Unsubscribe(callback: ICallback<ArgType>): void { //  } public Trigger(arg: ArgType, context?: any): void { //  } } 


At the output we get that now Callback (renamed to Delegate ) always implements the ICallback.

Trigger :

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
interface ICallback.

Trigger :

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
ICallback.

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
 ICallback. 

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
ICallback.

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
 ICallback. 

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
ICallback.

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
 ICallback. 

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
ICallback.

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
 ICallback. 

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
ICallback.

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
ICallback.

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
ICallback.

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
 ICallback. 

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
ICallback.

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
 ICallback. 

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
ICallback.

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
ICallback.

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
ICallback.

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
 ICallback. 

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .
ICallback.

Trigger
:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { // }

, :

export class MessagesRepo { public MessagesLoaded = new Events.Event<string[]>(); public ErrorHappened = new Events.Event<ErrorHappenedOptions>(); }

:

public Subscribe() { // this.Subscriptions.push(MessagesRepoInstance.MessagesLoaded.Subscribe(function (messages: string[], context?: any) { alert(messages && messages.length > 0 ? messages[0] : 'Nothing'); }, this)); // this.Subscriptions.push(MessagesRepoInstance.ErrorHappened.Subscribe(function (error: ErrorHappenedOptions) { alert(error.Error); }, this)); }

// context subscriber.MessagesRepo.MessagesLoaded.Trigger(['Test message 1'], this); // subscriber.MessagesRepo.ErrorHappened.Trigger({ Error: 'Test error 1' });

Unsubscribe

:

public Unsubscribe(callback: ICallback<ArgType>): void { var filteredList: ICallbackDesc<ArgType>[] = []; for (var i = 0; i < this.Callbacks.length; i++) { if (this.Callbacks[i].Callback !== callback) { filteredList.push(this.Callbacks[i]); } } this.Callbacks = filteredList; }

!== . . () - , . , , Unsubscribe . .. .., , , . .

? . , JS , , TS, . - .

.. :

public static Main(): void { var subscriber1: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); var subscriber2: Messages.SomeEventSubscriber = new Messages.SomeEventSubscriber(); subscriber1.Subscribe(); subscriber2.Subscribe(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 1'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 1' }); subscriber1.Destroy(); Messages.MessagesRepoInstance.MessagesLoaded.Trigger(['Test message 2'], this); Messages.MessagesRepoInstance.ErrorHappened.Trigger({ Error: 'Test error 2' }); }

2 'Test message 1' 'Test error 1', 'Test message 2' 'Test error 2'.



apply:

public Trigger: ICallback<ArgType> = function (arg: ArgType, context?: any) { var callbacks: ICallbackDesc<ArgType>[] = this.Callbacks; for (var i = 0; i < callbacks.length; i++) { callbacks[i].Callback.apply(callbacks[i].Subscriber, [arg, context]); } }

. .

Upd. . .

Source: https://habr.com/ru/post/185290/


All Articles