2012-04-25 38 views
7

假设我有一个对象,具有一定的属性和方法:对象文字和事件监听器,最佳实践?

var Form = { 
    name: 'sign-up', 

    show: function() {...}, 
    hide: function() {...}, 
    validate: function() {...}, 
    updateCurrency: function() {...}, 
    handleCheckBox: function() {...} 
} 

现在我想调用不同的方法,当某些事件在我的形式发生像这样:

$('#country-select').bind('change', function() { 
    Form.updateCurrency(); 
}); 

$("input[type='checkbox']").bind('change', function() { 
    Form.handleCheckBox(); 
}); 

我有很多的这些事件听众,坦率地说,我觉得他们丑陋地一个接一个地列出来,而不是直接与他们相关的对象联系在一起。有没有更优雅的方式将它们封装在我的对象文字Form?有最佳做法吗?

回答

6

我喜欢@gillesc的答案,它是在正确的轨道。 但是,我认为我们可以做得更好。

@gillesc回答的主要问题是它缺少事物的动态方面(例如事件处理程序),它也迫使你定义丑陋的回调函数。

所以继承人如何我认为你应该解决你的问题。

// Test object 
var testObj = { 
    // Our event handlers. 
    // Notice how we must only define the callback function name here. 
    // Not the function itself. The callback function must be defined in testObj. 
    handlers: { 
     '#form submit': 'onSubmit' 
    }, 
    // Method that will register all handlers to some selector 
    registerHandlers: function() { 
     var that = this; 
     // Go through the handlers list. 
     $.each(this.handlers, function(k, v) { 
      // Parsing the event to two different parts. 
      // 1. trigger event 
      // 2. selector 
      var split = k.split(" "), 
       el = split[0], 
       trigger = split[1]; 

      // Delegating the trigger to selector 
      $(document).delegate(el, trigger, that[v]); 
     }); 
    }, 
    // Our actual callback function 
    onSubmit: function(evt) { 
     evt.preventDefault(); 
     alert("submit"); 
    } 
}; 

这一切将如何工作?这很容易!我们只需要拨打testObj.registerHandlers()

JSFiddle demo

+0

此方法最好的是你不必在你的对象中有registerHandlers方法。我的意思是真的很快/很脏的例子。 [JSFiddle演示在这里](http://jsfiddle.net/E3xyz/3/) – Kirstein 2012-04-26 07:54:13

3

更好地组织你的标记,并将类添加到匹配事件处理程序方法的元素,以便您可以轻松创建处理程序列表并迭代它们以将它们绑定到目标元素。

Var Form = { 
    ...., 
    handlers: { 
     country: function() {}, 
     checkbox: function() {} 
    } 
}; 

$.each(FORMS.handlers, function(k, v) { 
    $('.' + k).on('change', v); 
}); 


<select class="country">....</select> 
<input class="checkbox" type="checkbox" /> 

然后,所有你需要做的就是添加类和处理程序来扩展

+0

这是完美的通用处理器(通过类名附加事件)。 – 2012-04-25 13:23:13

0

好了,你不需要更多的功能包装内的功能开始。你不能只:

$('#country-select').bind('change', Form.updateCurrency); 
$("input[type='checkbox']").bind('change', Form.handleCheckBox); 
+0

Yeaaah ..但是这忽略了我可能在回调中做的其他事情,比如preventDefault()。它也不会帮助我将事件处理程序封装在对象中,就像我想要做的那样。 – alnafie 2012-04-25 11:39:07

+0

在这种情况下,您可以包装bind方法(并且您的绑定方法包装您的事件处理程序),否则(以您的示例中的问题),你失去了对事件的引用,那么'handleCheckBox'如何处理你的复选框? – 2012-04-25 13:15:49