typescripteventsstrongly-typed-dataset

Strongly typed events package for typescript. How to add bound handelers to an event


I'm using the strongly typed events package in my app. This package is really useful for its events and how it handles those. I used the package like this for my app.

let onUpdate = new SignalDispatcher = new SignalDispatcher();
let component = new Component();
onUpdate.sub(component.Update);

void Update(){
 this.onUpdate.dispatch();
}

class Component {
 public Update(){
  //do stuff
 }
}

This works for one thing only. If you try to access "this" in the component update function. You won't get the component but the event. So I tried the function.bind(component) method like this.

onUpdate.sub(component.Update.bind(component));

This is a solution but now I have a problem unsubscribing. If I try to unsub the exact same bound method, the same way you would like a normal method, it would not unsubscribe. My guess is that it can't compare bound methods to each other. This always results in my method still subscribed.

Any alternatives or solutions I can try?


Solution

  • Looking at the code, that library confuses callback functions for subscription signatures.

    Within a proper subscribe->cancel architecture, method subscribe should always return a Subscription object, to allow a safe way to cancel the subscription.

    Since the question has been open for awhile, I will suggest an alternative events library sub-events for your consideration.

    Specifically for signals, as per the Signals page there, we can define a generic signal type:

    class Signal extends SubEvent<void> {} // reusable Signal type
    

    Then we can update your code to this:

    const onUpdate = new Signal();
    
    const component = new Component();
    
    // you can bind an event to the right context in 2 ways:
    const sub = onUpdate.subscribe(component.Update.bind(component));
    // or alternatively:
    const sub = onUpdate.subscribe(component.Update, {thisArg: component});
    
    
    void Update() {
        this.onUpdate.emit(); // emit the event (signal)
    }
    
    class Component {
        public Update(){
            //do stuff
        }
    }
    

    And then whenever you need to cancel the subscription, you just do this:

    sub.cancel();