0

我破解了 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"
  }
});

在我走得更远之前,有没有更好的方法来解耦?

4

1 回答 1

0

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

此外,使用 Marionette,您可以使用View 触发器,然后在布局中侦听 View.on("fooSelected")。

于 2013-03-02T01:47:33.763 回答