Javascript模式:条件事件处理程序

时间:2011-03-29 11:14:01

标签: javascript events event-handling design-patterns

例如某种类的类实例有一个状态(例如'active','inactive',...)。该实例还将点击事件附加到例如一个链接,但事件处理程序根据实例的状态执行不同的操作。

伪代码:

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
…

我想知道正确处理这个案例的好习惯是什么:

  • 通常使用哪种模式来实现这一目标?
  • 您是否在事件处理程序中使用条件?
  • 或者在状态发生变化时绑定和取消绑定处理程序?
  • 我错过了一些明显的其他/更好的解决方案吗?

更新

到目前为止阅读答案时,在处理程序中使用条件似乎有一种强烈倾向。虽然我暗中希望我可能错过了一个替代方案,但我有点期待这个。

我喜欢@ J-P的方法,因为它分别保持方法和状态的配对,这似乎比简单的switchif/else语句更具可扩展性和可维护性。 但是,我很想知道其他地方是否有不同的解决方法,也许是使用其他语言的例子?

5 个答案:

答案 0 :(得分:2)

通常使用哪种模式来实现这个?像this这样的东西 您是否在事件处理程序中使用条件?是的,见例子 或者是状态更改时绑定和取消绑定处理程序?不,但这是可能的。
我错过了一些明显的其他/更好的解决方案吗?我不这么认为

答案 1 :(得分:1)

我会保持相同的处理程序并在其中调用适当的方法。

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;

}());

答案 2 :(得分:1)

答案可能是情境性的,但与往常一样,除非存在性能问题,否则应该优先考虑简单性而非效率。

我认为在事件处理程序中检查条件是一种比绑定/解除绑定事件处理程序更简单,集中且更一致的方法。我经常使用全站click事件来检查与HTML元素关联的一些用户数据,以确定操作过程。

与您的示例类似,其中一项操作是“不做任何事情”,例如我设置了一个表示已被禁用的标志。另一种选择是删除点击处理程序。但这需要更多的代码来做同样的事情,并且意味着代码控制已被拆分:而它过去完全在点击处理程序中,现在它在点击处理程序中,以及添加或删除事件的其他内容。

如果事件处理程序在绑定到用户体验时会产生任何可察觉的性能影响,那么您可能想重新考虑这一点,但我不会想到很多情况。

答案 3 :(得分:0)

id说你只是检查点击事件。然后在click事件中检查实例状态

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

答案 4 :(得分:0)

你可以使用某种调度员:

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