2012-06-06 11 views
25

puedo asociar controladores de red troncal como Vistas:¿Cómo puedo adjuntar 2 manejadores al mismo evento?

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

Pero lo que si quiero adjuntar más de 1 manejador al mismo evento?

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

que podría crear un controlador personalizado como

Pero esto no parece ideal ...

+0

Estoy dispuesto a apostar "xxx": funciona "eventHandler1 eventHandler2", probando ahora –

+1

@AndyRay: ¿Cuánto quieres apostar? https://github.com/documentcloud/backbone/blob/master/backbone.js#L1242 –

+0

@muistooshort, entonces puedo decir que el método que debo usar ahora es: '" eventname ": function (e) {handler1 (e); handler2 (e)} '? – jm2

Respuesta

36

Este:

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

no funcionará porque events es un objeto literal y puede tener como máximo un par (clave, valor) en un objeto. Que probablemente sería lo mismo que decir:

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

Este CoffeeScript:

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

es funcionalmente idéntica a la versión de JavaScript y no funcionará por la misma razón. La idea de

Andy Ray de utilizar

'event selector': 'callback1 callback2'` 

no va a funcionar ya sea como Backbone no va a entender que debería dividir el valor de los espacios en blanco; Del mismo modo, esto:

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

no funcionará porque Backbone no sabe qué hacer con una matriz en este contexto.

Vistas unen sus eventos a través de delegateEvents y que tiene este aspecto:

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

Así method comienza como el valor para 'event selector'.Si se trata de una función de algo como:

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

entonces se utiliza tal cual, de lo contrario se convierte en una propiedad de this:

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

Si uno fuera negrita, se podría ajustar delegateEvents para comprender una matriz o cadena delimitada espacios en blanco:

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

un parche bastante simple como eso sería permitir el uso de una lista delimitada por espacios en blanco de los manipuladores:

'event selector': 'callback1 callback2' 

o una formación de manipuladores:

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

o incluso una matriz mixta de nombres y funciones de los métodos:

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

Si no desea aplicar un parche a su espina dorsal o reenviar un parche para los mantenedores de backbone entonces podría ir con su idea original de "envío manual":

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

+1 una buena respuesta completa –

9

He resuelto este problema mediante el uso de jQuery's event namespaces

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

Esto no es lo que los espacios de nombres evento fueron pensados ​​originalmente para, pero siempre y cuando no entren en conflicto con otros espacios de nombres no debe causar ningún problema.

El problema principal es que solo puede tener un valor por clave en un objeto y esto hace que las claves sean únicas.

+0

Niza. Terminé haciendo esto: 'events: { 'click.first a': 'hideAll', 'click.second a': 'showContent' }' – eightyfive

Cuestiones relacionadas