2012-04-02 7 views
7
var test = { } 
$(test).on("testEvent", function(){ 
    console.log("testEvent has fired"); 
}); 
$.event.trigger("testEvent"); 

Estoy tratando de usar jQuery para hacer un mecanismo de publicación/suscripción utilizando eventos. Necesito poder adjuntar eventos a objetos que no sean DOM y poder hacer que todos disparen desde un único disparador global. Esperaba que el código anterior funcionara, pero no dio como resultado la activación de testEvent para el objeto de prueba.

Tenga en cuenta que habrá múltiples objetos a los que se suscribirá un evento. Un único $ .event.trigger debería desencadenar todos esos eventos.

Ten en cuenta que este código funciona bien:

$('#someID').on("testEvent", function() { 
console.log('testEvent has fired from DOM element'); 
}) 
$.event.trigger("testEvent"); 
+0

El motivo por el que el evento no se activa es porque el objeto no forma parte del DOM. Cuando disparo $ .event.trigger, enciendo el evento y burbujeo hacia arriba a través del DOM. Viendo que el objeto no es parte del DOM, no se dispara. Lo que realmente estoy buscando aquí es de alguna manera disparar eventos dentro de objetos que no son DOM globalmente usando jQuery. Estoy tratando de evitar tener que usar algo como AmplifyJS para lograr esto. – crv

+2

La única manera de activar el evento que ha publicado es con '$ (test) .trigger (" testEvent ");'. –

+1

Si no pasa un elemento a '$ .event.trigger' y el evento que se desencadena no es un evento global, no activará un evento. Vea el bloque de código que comienza en la línea 3104 de http://code.jquery.com/jquery-1.7.2.js. Dado que este es un método no documentado, tenemos que ir al código para ver qué hace. –

Respuesta

8

Después de hacer algunas investigaciones, parece como si jQuery 1.7 proporciona una manera fácil de introducir un mecanismo de publicación/suscripción. (Encontrado here) Con el fin de tener una publicación/suscripción mecanismo el código siguiente se puede utilizar:

(function ($, window, undefined) { 
    var topics = {}; 

    jQuery.Topic = function (id) { 
     var callbacks, method, topic = id && topics[id]; 
     if (!topic) { 
      callbacks = jQuery.Callbacks(); 
      topic = { 
       publish: callbacks.fire, 
       subscribe: callbacks.add, 
       unsubscribe: callbacks.remove 
      }; 
      if (id) { 
       topics[id] = topic; 
      } 
     } 
     return topic; 
    }; 
}) 

Con el fin de suscribirse a un evento de la siguiente se realiza:

$.Topic("message").subscribe(function() { 
    console.log("a publish has occurred"); 
}); 

Para publicar aparece un mensaje que dice lo siguiente:

$.Topic("message").publish(data); 

"Mensaje" es el nombre del evento. El argumento de datos contiene cualquier información que quiera pasar a los suscriptores.

Para cancelar la suscripción debe pasar la función que se ha suscrito:

$.Topic("message").unsubscribe(funcSubscribedToBefore); 
0

En los navegadores modernos (si he read the source for Underscore.js derecha) le permiten enlazar eventos a objetos DOM no de forma nativa. De lo contrario, tendrás que usar algo como la función .bind de subrayado. Entonces depende de qué navegadores necesites apoyar.

Editar:

Ok, se unen importa, yo estaba pensando en Underscore.js es el mismo que con la espina dorsal. El Backbone tiene su propio módulo de eventos que aparentemente vincula el evento.

binding events to dynamic objects in underscore/backbone

+0

y para añadir más insultos a la injuria, Backbone.Events ahora usa la sintaxis "on/off", no su enlace previo, etc. sintaxis. Lo sabía. – JayC

0

recientemente he utilizado enfoque Ben Alman, y funcionó muy bien!

/* jQuery Tiny Pub/Sub - v0.7 - 10/27/2011 
* http://benalman.com/ 
* Copyright (c) 2011 "Cowboy" Ben Alman; Licensed MIT, GPL */ 

(function ($) { 

    var o = $({}); 

    $.subscribe = function() { 
     o.on.apply(o, arguments); 
    }; 

    $.unsubscribe = function() { 
     o.off.apply(o, arguments); 
    }; 

    $.publish = function() { 
     o.trigger.apply(o, arguments); 
    }; 

}(jQuery)); 

Uso:

$.subscribe('eventName', function (event) { 
    console.log(event.value); 
}); 

$.publish({ type: 'eventName', value: 'hello world' }); 

Ver https://gist.github.com/addyosmani/1321768 para más información.

Cuestiones relacionadas