2012-02-11 50 views
1

我正在学习javascript,并且有关于使用jQuery监听和分派事件的问题。Javascript MVC +使用jQuery监听和分派事件

在我的模型,我有一个触发事件变化的函数:

Model.prototype.setCurrentID = function(currentID) { 
    this.currentID = currentID; 
    $('body').trigger('change'); 
} 

触发事件需要的元素,所以我把它绑定到“身体”。这是好的做法还是不好的做法?

在AS3中,其中我更熟悉,我只会派一个全球性的事件从模型,传递一个常量的值,侦听此事件与模型的实例:

var model:Model = new Model(); 
model.addEventListener(CONST_VALUE, handlerFunction); 

在jQuery的,我的浏览对象中,我需要一个元素附加到听众一样,所以我把它绑定到“身体”再次声明:

​​

它的工作,但我在你拿有兴趣的主题。

+0

看起来你在$('body')中有一个额外的右括号“}”。 function updateSomething(evt){console.log('updating ...')} extra --->} – 2012-02-11 18:00:46

回答

2

我推荐使用私人调度程序,这个程序不公开给公众。
例如,如果用户或插件解除绑定在所述主体(调度员)的所有事件的逻辑可能失败:

$('body').unbind(); 

这可避免通过创建DOM节点,而不是把它暴露在端用户(不追加到DOM):

var dispatcher = $('<div />'); 

Model.prototype.setCurrentID = function(currentID) { 
    this.currentID = currentID; 
    dispatcher.trigger('change'); 
} 

var View = function(model, controller) { 
    this.model = model; 
    this.controller = controller; 

    dispatcher.bind('change',function(evt) { updateSomething(evt); }); 
    function updateSomething(evt){console.log('updating...')} 
} 

另一件好事开发事件的编程应用程序使用jQuery的时候有想到的是,jQuery的允许你绑定/触发自定义事件,并允许您to namespace your events。这样,您就可以控制更有效地事件绑定和触发:

Model.prototype.setCurrentID = function(currentID) { 
    this.currentID = currentID; 
    dispatcher.trigger('modelIdChange.' + this.currentID); 
} 
Model.prototype.destroy = function() { 
    // unbind all the event handlers for this particular model 
    dispatcher.unbind('.'+this.currentID); 
} 

var View = function(model, controller) { 
    /*...*/ 

    // this will be triggered for all the changes 
    dispatcher.bind('modelIdChange',function(evt) { updateSomething(evt); }); 

    // this will be triggered only for the model with the id "id1" 
    dispatcher.bind('modelIdChange.id1',function(evt) { updateSomething(evt); }); 

    /*...*/ 
} 
+0

非常棒!这是非常非常有帮助的! – worked 2012-02-15 12:30:48

0

我的反对意见是:

  • 我不会绑定具有相同的名称作为broswer事件的事件,可能会有干扰。
  • 如果您有一个模型,则您的代码有效,但如果您有两个或更多模型,则需要将它们分开,而不是在同一元素上绑定/触发两者。

如何:

Model.prototype.bind = function(event, func) { 
    if (!this._element) this._element = $('<div>'); 
    this._element.bind(this.name+'_'+event, $.proxy(func, this)); 
    return this; 
}; 
Model.prototype.trigger = function(event) { 
    if (!this._element) this._element = $('<div>'); 
    this._element.trigger(this.name+'_'+event); 
    return this; 
}; 

这样,你解决这两个。注意我将this.name+'_'附加到事件名称(假定每个模型都有某种名称,并确保事件与浏览器事件不匹配),但您也可以删除前缀。

我还在绑定中使用$.proxy,因此事件处理函数中的this引用模型。

var View = function(model, controller) { 
    .... 
    model.bind('change', function() {...}); 
} 
2

我走了一步,创建自定义的全球性事件。使用jQuery你可以触发一个全球性的自定义事件,像这样:

$.event.trigger('change'); 

元素都可以订阅该事件:

$('#myDiv').bind('change', function() { 
    console.log($(this)); 
}); 

在事件处理程序的this关键字是订阅的触发的DOM元素事件。

+0

也是一个非常好的观点!谢谢! – worked 2012-02-15 12:31:44