2012-06-06 70 views
25

我可以附加處理程序主幹意見,如:如何將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 );處理程序2(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'` 

將無法​​正常工作或作爲骨幹不會明白,它應該在空白分裂值;同樣,這個:

'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' ] 

如果你不想修補骨幹或轉發這樣的修補程序給骨幹維護人員,那麼你可以去你的原始「手動調度」的想法:

'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

不錯的。我最終這樣做了: 'events:{ 'click.first a':'hideAll', 'click.second a':'showContent' } – eightyfive

相關問題