Javascript pattern: Conditional event handler
Given e.g. a class instance of some sort has开发者_StackOverflow中文版 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?
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
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;
}());
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.
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;
}
}
You use can some kind of dispatcher:
$link.on('click', function () {
(state ? A : B).call();
});
精彩评论