2012-06-06 3 views
25

я могу прикрепить обработчик Backbone Просмотры как:Как подключить 2 обработчика к одному и тому же событию?

var TodoView = Backbone.View.extend({ 
    events: { 
     "xxx": "eventHandler1" 
     "yyy": "eventHandler2" 
    } 
}); 

Но что, если я хочу, чтобы прикрепить более 1 обработчик то же событие?

var TodoView = Backbone.View.extend({ 
    events: { 
     "xxx": "eventHandler1" 
     "yyy": "eventHandler2" 
     "xxx": "eventHandler3" // this isn't valid ... at least in CoffeeScript 
    } 
}); 

я мог бы создать пользовательский обработчик как

Но это не кажется идеальным ...

+0

Я готов сделать ставку «xxx»: «eventHandler1 eventHandler2» работает, тестирование сейчас –

+1

@AndyRay: Сколько вы хотите делать ставки? https://github.com/documentcloud/backbone/blob/master/backbone.js#L1242 –

+0

@muistooshort, поэтому могу ли я сказать, что метод, который я должен использовать сейчас, это: '" eventname ": function (e) {handler1 (e); handler2 (e)} '? – jm2

ответ

36

Это:

events: { 
    "xxx": "eventHandler1", 
    "yyy": "eventHandler2", 
    "xxx": "eventHandler3" 
} 

не будет работать, потому что events является литералом объекта, и вы можете иметь не более одной пары (ключ, значение) в объекте. Это, вероятно, будет таким же, как говорят:

events: { 
    "xxx": "eventHandler3", 
    "yyy": "eventHandler2" 
} 

Это CoffeeScript:

events: 
    "xxx": "eventHandler1" 
    "yyy": "eventHandler2" 
    "xxx": "eventHandler3" 

функционально идентична версии JavaScript и не будет работать по той же причине. Идея

Энди Рея с помощью

'event selector': 'callback1 callback2'` 

не будет работать либо как Backbone не поймет, что он должен разделить значение на пробельных; Аналогично, это:

'event selector': [ 'callback1', 'callback2' ] 

не будет работать, потому что 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... 
    } 
} 

Так method начинается в качестве значения для 'event selector'.Если это функция от чего-то вроде:

'event selector': function() { ... } 

то он используется как есть, в противном случае она превращается в свойство this:

method = this[events[key]]; // i.e. method = this[method] 

Если один были смелы, можно регулировать 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... 
} 

довольно простой патч, как, что позволит вам использовать пробельные разделители список обработчиков:

'event selector': 'callback1 callback2' 

или массив обработчиков:

'event selector': [ 'callback1', 'callback2' ] 

или даже смешанный массив имен и функций метода:

'event selector': [ 'callback_name1', function() { ... }, 'callback_name2' ] 

Если вы не хотите, чтобы исправить ваш позвоночник или вперед такой патч для поддерживающих Backbone, то вы можете пойти с оригинальной идеей «ручной диспетчеризации»:

'event selector': 'dispatcher' 
//... 
dispatcher: function(ev) { 
    this.handler1(ev); 
    this.handler2(ev); 
} 
+0

+1 хороший, тщательный ответ –

9

Я решил эту проблему с помощью jQuery's event namespaces

var TodoView = Backbone.View.extend({ 
    events: { 
     "xxx.handler1": "eventHandler1", 
     "yyy": "eventHandler2", 
     "xxx.handler3": "eventHandler3" 
    } 
}); 

Это не является то, что событие Пространства имен были первоначально предназначены для, но до тех пор, пока они не вступают в противоречие с другими пространствами имен не должно вызывать проблемы.

Основная проблема заключается в том, что вы можете иметь только одно значение для ключа в объекте, и это делает ключи уникальными.

+0

Ницца. Я закончил это: 'события: { 'click.first a': 'hideAll', 'click.second a': 'showContent' }' – eightyfive

Смежные вопросы