我正在学习javascript并且对使用jQuery监听和调度事件有疑问。
在我的模型中,我有一个触发更改事件的函数:
Model.prototype.setCurrentID = function(currentID) {
this.currentID = currentID;
$('body').trigger('change');
}
触发事件需要一个元素,所以我将它绑定到'body'。这是好习惯还是坏习惯?
在我更熟悉的AS3中,我只是从模型中调度一个全局事件,传入一个const值,用一个Model实例监听这个事件:
var model:Model = new Model();
model.addEventListener(CONST_VALUE, handlerFunction);
在jQuery中,在我的View对象中,我还需要将一个元素附加到侦听器,所以我再次将它绑定到'body':
var View = function(model, controller) {
var model;
var controller;
this.model = model;
this.controller = controller;
$('body').change(function(evt) { updateSomething(evt); });
function updateSomething(evt){console.log('updating...')};
}
这是有效的,但我对你对这个主题的看法感兴趣。
答案 0 :(得分: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); });
/*...*/
}
答案 1 :(得分:2)
我会更进一步,创建自定义全局事件。使用jQuery,您可以触发全局自定义事件,如下所示:
$.event.trigger('change');
任何元素都可以订阅该事件:
$('#myDiv').bind('change', function() {
console.log($(this));
});
事件处理程序中的this
关键字是订阅触发事件的DOM元素。
答案 2 :(得分:0)
我的反对意见是:
怎么样:
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() {...});
}