1

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:

  • Which patterns are commonly in use to achieve this?
  • Are you using a conditional in the event handler?
  • Or are binding and unbinding handlers when the state changes?
  • Am I missing some obvious other/better solution?

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?

5 Answers 5

2

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

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the example. + for the conditional, it seems.
Again another proof that simply linking inside answers is a bad habit... I'd be interested in that example.
@Salketer You're absolutely right. To my defense: the answer is almost 8 years old, that's light years in coding space. I've tried to find the code, but it's in dev null I suppose.
@KooiInc no worries... 9 years ago you couldn't expect this question to be google's top link for this pattern.
1

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;

}());

3 Comments

Thanks! This method — while more verbose than a simple conditional — keeps things tidy. Might consider that for a case with more than just a few 'states'. + for the conditional.
'active' => 'a': Unexpected token =
Yep, no hash rockets in JS ;) .
1

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.

1 Comment

Thanks for a comprehensive answer!
0

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;
 }     
}

Comments

0

You use can some kind of dispatcher:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.