son sitios script que pasar navegador manejo los llamar funciones funcion eventos evento ejemplos desde javascript backbone.js backbone-events backbone-views

javascript - sitios - ¿Cómo puedo adjuntar 2 manejadores al mismo evento?



manejo de eventos en sitios web (2)

Puedo adjuntar controladores a vistas principales como:

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

Pero, ¿qué ocurre si quiero adjuntar más de 1 controlador al mismo evento?

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

Podría crear un controlador personalizado como

function compositeXXX() { eventHandler1(); eventHandler2 }

Pero esto no parece ideal ...


Esta:

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

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

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

Este CoffeeScript:

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

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

La idea de Andy Ray de usar

''event selector'': ''callback1 callback2''`

tampoco funcionará, ya que Backbone no comprenderá que debe dividir el valor en 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.

Las vistas vinculan sus eventos a través de delegateEvents y se ve así:

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

Entonces el method comienza como el valor para ''event selector'' . Si es una función de algo como:

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

luego se usa 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 cadena delimitada por un conjunto o por 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 ese le permitiría usar una lista de manipuladores delimitada por espacios en blanco:

''event selector'': ''callback1 callback2''

o una variedad de controladores:

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

o incluso una combinación mixta de nombres y funciones de métodos:

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

Si no quiere parchear su Backbone o reenviar dicho parche a 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); }


Resolví este problema usando los espacios de nombres de eventos de jQuery

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

Esto no es para lo que originalmente se diseñaron los espacios de nombres de eventos, pero siempre y cuando no entren en conflicto con otros espacios de nombres, no debería causar un problema.

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