2012-06-06 18 views
25

Ich kann Handler Backbone Ansichten wie anbringt:Wie kann ich zwei Handler an dasselbe Ereignis anhängen?

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

Aber was, wenn ich will mehr als 1 Handler auf das gleiche Ereignis befestigen?

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

Ich konnte einen benutzerdefinierten Handler wie

erstellen Aber dies scheint nicht ideal ...

+0

Ich bin bereit zu wetten "xxx": "eventHandler1 eventHandler2" funktioniert, testet jetzt –

+1

@AndyRay: Wie viel möchten Sie wetten? https://github.com/documentcloud/backbone/blob/master/backbone.js#L1242 –

+0

@muistooshort, also kann ich sagen, die Methode, die ich jetzt verwenden sollte, ist: '" eventname ": function (e) {handler1 (e); handler2 (e)} '? – jm2

Antwort

36

Dies:

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

wird nicht funktionieren, weil events ist ein Objektliteral und Sie können höchstens ein (Schlüssel-, Wert-) Paar in einem Objekt haben. Das wäre wahrscheinlich das gleiche wie zu sagen:

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

Diese Coffee:

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

an die JavaScript-Version funktional identisch ist und wird aus dem gleichen Grund nicht funktionieren.

Andy Ray Idee von

mit
'event selector': 'callback1 callback2'` 

wird nicht funktionieren entweder als Backbone nicht verstehen, dass sie den Wert auf Leerzeichen aufgeteilt werden soll; In ähnlicher Weise folgt aus:

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

wird nicht funktionieren, weil Backbone nicht wissen, was in diesem Zusammenhang mit einer Reihe zu tun.

Ansichten binden ihre Veranstaltungen durch delegateEvents und sieht wie folgt aus:

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 beginnt für 'event selector' als Wert aus.Wenn es sich um eine Funktion von etwas ist wie:

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

dann wird es verwendet, wie sie ist, sonst ist es zu einer Eigenschaft von this umgewandelt wird:

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

Wenn man fett, so könnte man delegateEvents einstellen

// 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... 
} 

ein ziemlich einfaches Pflaster wie das Sie erlauben würde, eine Leerzeichen getrennte Liste von Handler zu verwenden: einen Array oder Leerzeichen getrennte Zeichenfolge zu verstehen

'event selector': 'callback1 callback2' 

oder ein Array von Handler:

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

oder auch eine gemischte Anordnung von Methodennamen und Funktionen:

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

Wenn Sie wollen Ihr Backbone nicht patchen oder weiterleiten So ein Patch an die Backbone-Betreuer, dann könntest du mit deiner ursprünglichen "Manual Dispatching" Idee gehen:

+0

+1 eine gute, gründliche Antwort –

9

Ich löste dieses Problem durch jQuery's event namespaces mit

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

ist nicht das, was Ereignis Namespaces wurden ursprünglich für, aber solange sie mit anderen Namensräumen nicht tun kollidieren sollte es nicht ein Problem verursachen.

Das Hauptproblem ist nur, dass Sie nur einen Wert pro Schlüssel in einem Objekt haben können, und das macht die Schlüssel einzigartig.

+0

Nice one. Ich endete dabei: 'Ereignisse: { 'click.first a': 'versteckenAll', 'click.second a': 'showContent' }' – eightyfive

Verwandte Themen