Backbone事件不能与object.function一起使用

时间:2014-11-20 13:51:02

标签: javascript backbone.js

我正在尝试通过对象委派我的事件。但事件不会激发,如果我直接引用它("click .formations div":this.movement.leaveCell)它会抛出一个JS错误

events: {
    "click .formations div":"enterCell", //option A
    "click .save ":"movement.leaveCell", //option B
    "click .save ":function(ev){this.movement.leaveCell(ev, this);}, //option C currently works
},
enterCell: function(ev){
    $(ev.currentTarget).addClass('highlight');
},
movement: {
    leaveCell: function(ev){
        $(ev.currentTarget).removeClass('highlight');
    }
},

如何让option B工作?

1 个答案:

答案 0 :(得分:1)

从Backbone的源代码中,您可以看到负责委派delagateEvents的事件的方法

delegateEvents: function(events) {
      if (!(events || (events = _.result(this, 'events')))) return this;
      this.undelegateEvents();
      for (var key in events) {
        var method = events[key];
        if (!_.isFunction(method)) method = this[events[key]];
        if (!method) continue;

        var match = key.match(delegateEventSplitter);
        var eventName = match[1], selector = match[2];
        method = _.bind(method, this);
        eventName += '.delegateEvents' + this.cid;
        if (selector === '') {
          this.$el.on(eventName, method);
        } else {
          this.$el.on(eventName, selector, method);
        }
      }
      return this;
    },

从这里您可以看到delegateEvents()的原生实现无法处理您的情况。它会尝试搜索不正确的movement.leaveCell

如果您想强制Backbone.View以您的方式执行此操作,则应重写此方法。


<强>更新

Here使用重写的delegateEvents方法很简单。

Backbone.View.prototype.delegateEvents = function(events) {
      if (!(events || (events = _.result(this, 'events')))) return this;
      this.undelegateEvents();
      for (var key in events) {
        var method = events[key];
          if (!_.isFunction(method)) {
          var behaviors = method.split('.');
              if(behaviors.length > 1) {
                  method = this[behaviors[0]][behaviors[1]];
              } else {
                  method = this[events[key]];
              }

          }
        if (!method) continue;

        var match = key.match(/^(\S+)\s*(.*)$/);
        var eventName = match[1], selector = match[2];
        method = _.bind(method, this);
        eventName += '.delegateEvents' + this.cid;
        if (selector === '') {
          this.$el.on(eventName, method);
        } else {
          this.$el.on(eventName, selector, method);
        }
      }
      return this;
    };

此示例适用于一个级别的深层对象,但不再适用。

我建议您查看Marionette.jsMarionette.Behaviors,它也是为了区分视图及其行为。