polarblau
polarblau

Reputation: 17734

Javascript pattern: Conditional event handler

Given e.g. a class instance of some sort has a state (e.g. 'active', 'inactive', …). The instance also attaches a click event to e.g. a link but the event handler does something different depending on the instance's state.

Pseudo code:

IF instance state IS 'active' AND link is clicked THEN call function A
IF instance state IS 'inactive' AND link is clicked THEN call function B
…

I'm wondering what's considered good practice to handle this case properly:


UPDATE

While reading the answers so far, there seems to be a strong tendency towards the usage of a conditional within the handler. While I had secretly hoped that I might have missed an alternative, I've sort of expected this.

I like @J-P's approach since it keeps the pairing of method and state separately, which seems more scaleable and maintainable than a simple switch or if/else statement. However, I'd be very interested to hear if this is solved differently elsewhere, maybe using an example from a different language?

Upvotes: 1

Views: 9992

Answers (5)

James
James

Reputation: 111910

I would keep the same handler and call the appropriate method within.

var Foo = (function(){

    function Foo() {

        this.state = 'active';

    }

    Foo.methodMapping = {
        active: 'a',
        inactive: 'b'
    };

    Foo.prototype = {

        a: function(){}.
        b: function(){},

        handler: function(el) {

            // This'll handle the event, I guess
            // (Assuming `this` refers to instance, not element)

            var state = this.state;
            if (state in Foo.methodMapping) {
                return this[Foo.methodMapping[state]].apply(this, arguments);
            } else {
                // (prob don't need to cover this case)
            }

        }

    };

    return Foo;

}());

Upvotes: 1

masylum
masylum

Reputation: 22371

You use can some kind of dispatcher:

$link.on('click', function () {
  (state ? A : B).call();
});

Upvotes: 0

KooiInc
KooiInc

Reputation: 122916

Which patterns are commonly in use to achieve this? Something like this
Are you using a conditional in the event handler? Yes, see example
Or are binding and unbinding handlers when the state changes? Nope, but it's a possibility.
Am I missing some obvious other/better solution? I don't think so

Upvotes: 2

Quaze
Quaze

Reputation: 73

id say you just check the click event. Then in the click event check the instance state

link.live('click', function() {
 switch(instance.state){
  case 'active': function A(); break;
  case 'inactive': function B(); break;
 }     
}

Upvotes: 0

Jamie Treworgy
Jamie Treworgy

Reputation: 24344

The answer may be situational, but as always, one should favor simplicity over efficiency, unless there is a performance problem.

I think that checking conditions in an event handler is a simpler, centralized, and more consistent approach than binding/unbinding event handlers. I often use sitewide click event that checks some user data associated with the HTML element to determine the course of action.

Similar to your example, one of those actions is "don't do anything", e.g. I've set a flag that indicates it's been disabled. The other option would be to remove the click handler. But this requires more code to do the same thing, and means code control has been split: whereas it used to be entirely in the click handler, now it's in the click handler, and something else that adds or removes the event.

If the event handler has any perceptible performance impact when bound to the user experience, then maybe you'd want to reconsider this, but I can't think of many situations when it would.

Upvotes: 1

Related Questions