This:
events: {
"xxx": "eventHandler1",
"yyy": "eventHandler2",
"xxx": "eventHandler3"
}
won't work because events
is an object literal and you can have at most one (key,value) pair in an object. That would probably be the same as saying:
events: {
"xxx": "eventHandler3",
"yyy": "eventHandler2"
}
This CoffeeScript:
events:
"xxx": "eventHandler1"
"yyy": "eventHandler2"
"xxx": "eventHandler3"
is functionally identical to the JavaScript version and won't work for the same reason.
Andy Ray's idea of using
'event selector': 'callback1 callback2'`
won't work either as Backbone won't understand that it should split the value on whitespace; similarly, this:
'event selector': [ 'callback1', 'callback2' ]
won't work because Backbone doesn't know what to do with an array in this context.
Views bind their events through delegateEvents
and that looks like this:
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...
}
}
So method
starts out as the value for 'event selector'
. If it is a function from something like:
'event selector': function() { ... }
then it is used as-is, otherwise it is converted to a property of this
:
method = this[events[key]]; // i.e. method = this[method]
If one were bold, one could adjust delegateEvents
to understand an array or whitespace delimited string:
// 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...
}
A fairly simple patch like that would allow you to use a whitespace delimited list of handlers:
'event selector': 'callback1 callback2'
or an array of handlers:
'event selector': [ 'callback1', 'callback2' ]
or even a mixed array of method names and functions:
'event selector': [ 'callback_name1', function() { ... }, 'callback_name2' ]
If you don't want to patch your Backbone or forward such a patch to the Backbone maintainers then you could go with your original "manual dispatching" idea:
'event selector': 'dispatcher'
//...
dispatcher: function(ev) {
this.handler1(ev);
this.handler2(ev);
}