delegateEvents hack for decoupling events

时间:2013-03-01 21:05:49

标签: javascript backbone.js marionette

我攻击了Backbone来源,但现在我正在寻找建议让它变得更好。

以下是方法delegateEvents的来源:

delegateEvents: function (events) {
  if (!(events || (events = _.result(this, 'events')))) return;
  this.undelegateEvents();
  for (var key in events) {
    var method = events[key];
    if (!_.isFunction(method)) method = this[events[key]];
    if (!method) throw new Error('Method "' + events[key] + '" does not exist');
    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);
    }
  }
},

以下是我入侵的内容(还没有完全准备就绪,嗯?):

delegateEvents: function (events) {
  if (!(events || (events = _.result(this, 'events')))) return;
  this.undelegateEvents();
  for (var key in events) {
    var method = events[key];
    var special = false;
    if (method.indexOf('REF->') != -1) {
      special = true;
    } else {
      if (!_.isFunction(method)) method = this[events[key]];
      if (!method) throw new Error('Method "' + events[key] + '" does not exist');
    }
    var match = key.match(delegateEventSplitter);
    var eventName = match[1],
      selector = match[2];
    if (!special) method = _.bind(method, this);
    eventName += '.delegateEvents' + this.cid;
    if (selector === '') {
      if (!special) this.$el.on(eventName, method);
    } else {
      if (special) {
        var specialMethod = method.replace('REF->', '');
        eval('this.$el.on(eventName, selector, ' + specialMethod + ');');
      } else {
        this.$el.on(eventName, selector, method);
      }
    }
  }
},

用例:

我想从视图中删除逻辑,或者只是将其重定向到视图外的函数。原因很简单 - 我正在考虑页面,而不仅仅是视图,我真的使用Marionette Layouts来促进这一点;每个布局包含多个视图块,我希望页面上的所有视图委派都在一个地方。

所以,如果这是标准的话:

View = Backbone.View.extend({
  events: {
    "click li.foo": "fooSelected"
  },
  fooSelected: function (e) {

  }
});

黑客的工作原理如下:

View = Backbone.View.extend({
  events: {
    "click li.foo": "REF->MyApp.Page.fooSelected"
  }
});

在我继续前进之前,是否有更好的方法将其解耦?

1 个答案:

答案 0 :(得分:0)

使用行if (!_.isFunction(method)) method = this[events[key]]; Backbone已经在检查你是否给它调用了一个函数而不是视图对象上的方法键。看到这个小提琴:http://jsfiddle.net/h4eWn/

此外,使用Marionette,您可以使用View triggers,然后在布局中收听View.on(“fooSelected”)。