Javascript MVC +使用jQuery监听和调度事件

时间:2012-02-11 17:44:27

标签: javascript jquery

我正在学习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...')};
}

这是有效的,但我对你对这个主题的看法感兴趣。

3 个答案:

答案 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)

我的反对意见是:

  • 我不会绑定与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() {...});
}