jm2*_*jm2 25 javascript backbone.js backbone-events backbone-views
我可以将处理程序附加到Backbone Views,如:
var TodoView = Backbone.View.extend({
events: {
"xxx": "eventHandler1"
"yyy": "eventHandler2"
}
});
Run Code Online (Sandbox Code Playgroud)
但是如果我想在同一个事件中附加多个处理程序呢?
var TodoView = Backbone.View.extend({
events: {
"xxx": "eventHandler1"
"yyy": "eventHandler2"
"xxx": "eventHandler3" // this isn't valid ... at least in CoffeeScript
}
});
Run Code Online (Sandbox Code Playgroud)
我可以创建一个自定义处理程序
function compositeXXX() { eventHandler1(); eventHandler2 }
Run Code Online (Sandbox Code Playgroud)
但这似乎并不理想......
mu *_*ort 36
这个:
events: {
"xxx": "eventHandler1",
"yyy": "eventHandler2",
"xxx": "eventHandler3"
}
Run Code Online (Sandbox Code Playgroud)
将无法工作,因为它events是一个对象文字,你可以在一个对象中最多有一个(键,值)对.这可能与说:
events: {
"xxx": "eventHandler3",
"yyy": "eventHandler2"
}
Run Code Online (Sandbox Code Playgroud)
这个CoffeeScript:
events:
"xxx": "eventHandler1"
"yyy": "eventHandler2"
"xxx": "eventHandler3"
Run Code Online (Sandbox Code Playgroud)
功能上与JavaScript版本相同,但由于同样的原因不起作用.
安迪雷的使用想法
'event selector': 'callback1 callback2'`
Run Code Online (Sandbox Code Playgroud)
不会工作,因为Backbone不会理解它应该在空白上拆分值; 同样,这个:
'event selector': [ 'callback1', 'callback2' ]
Run Code Online (Sandbox Code Playgroud)
将无法工作,因为Backbone不知道在这种情况下如何处理数组.
视图绑定它们的事件delegateEvents,看起来像这样:
delegateEvents: function(events) {
// Some preamble that doesn't concern us here...
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');
// And some binding details that are of no concern either...
}
}
Run Code Online (Sandbox Code Playgroud)
所以method从价值开始'event selector'.如果它是一个函数,如:
'event selector': function() { ... }
Run Code Online (Sandbox Code Playgroud)
然后它按原样使用,否则转换为以下属性this:
method = this[events[key]]; // i.e. method = this[method]
Run Code Online (Sandbox Code Playgroud)
如果一个是粗体,可以调整delegateEvents以理解数组或空格分隔的字符串:
// Untested code.
var methods = [ ];
if (_.isArray(method))
methods = method;
else if (_.isFunction(method))
methods = [ method ];
else
methods = method.split(/\s+/);
for (var i = 0; i < methods.length; ++i) {
method = methods[i];
if (!_.isFunction(method))
method = this[method];
// And the rest of the binding stuff as it is now with a possible adjustment
// to the "method does not exist" exception message...
}
Run Code Online (Sandbox Code Playgroud)
一个相当简单的补丁允许您使用以空格分隔的处理程序列表:
'event selector': 'callback1 callback2'
Run Code Online (Sandbox Code Playgroud)
或一组处理程序:
'event selector': [ 'callback1', 'callback2' ]
Run Code Online (Sandbox Code Playgroud)
甚至是方法名称和函数的混合数组:
'event selector': [ 'callback_name1', function() { ... }, 'callback_name2' ]
Run Code Online (Sandbox Code Playgroud)
如果您不想修补Backbone或将这样的补丁转发给Backbone维护者,那么您可以使用原始的"手动调度"想法:
'event selector': 'dispatcher'
//...
dispatcher: function(ev) {
this.handler1(ev);
this.handler2(ev);
}
Run Code Online (Sandbox Code Playgroud)
我通过使用jQuery的事件命名空间解决了这个问题
var TodoView = Backbone.View.extend({
events: {
"xxx.handler1": "eventHandler1",
"yyy": "eventHandler2",
"xxx.handler3": "eventHandler3"
}
});
Run Code Online (Sandbox Code Playgroud)
这不是最初用于命名空间的事件名称空间,但只要它们不与其他名称空间冲突,它就不会导致问题.
主要问题是,对象中每个键只能有一个值,这使得键唯一.
| 归档时间: |
|
| 查看次数: |
4679 次 |
| 最近记录: |