我破解了 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"
}
});
在我走得更远之前,有没有更好的方法来解耦?