30

¿Hay complementos jQuery de Event Driven Architecture?jQuery plugin for Event Driven Architecture?

Paso 1: La suscripción

alt text
Los abonados suscribirse al controlador de eventos en el medio, y pasan en un método de devolución de llamada, así como el nombre del evento que están escuchando ... para

es decir, los dos suscriptores verdes estarán escuchando eventos p0. Y el suscriptor azul estará escuchando eventos p1.


Paso 2: El evento p0 es disparado por otro componente al controlador de eventos

alt text

  1. Un evento p0 es despedido a la controlador de eventos
  2. El controlador de eventos notifica que es suscriptores del evento, llamando a los métodos de devolución de llamada que especificaron cuando se suscribieron en Paso 1: Suscripción.

Tenga en cuenta que no se notifica al suscriptor azul porque no estaba escuchando eventos p0.


Paso 3: El evento p1 se dispara un componente al controlador de eventos

alt text

El evento p1 es disparado por otro componente

Al igual que antes, excepto que ahora el azul el suscriptor recibe el evento a través de su devolución de llamada y los otros dos suscriptores verdes no reciben el evento.

Images by leeand00, on Flickr

Me parece que no puede encontrar uno, pero mi conjetura es que simplemente lo llaman algo más en Javascript/jQuery

También hay un nombre para este patrón? Debido a que no es solo un editor/suscriptor básico, tiene que llamarse algo más, creo.

+0

Por favor, hágamelo saber si no está claro lo que estoy hablando. – leeand00

Respuesta

48

Es probable que no necesitan una complemento para hacer esto. En primer lugar, el DOM en sí mismo es completamente impulsado por eventos. Puede usar la delegación de eventos para escuchar todos los eventos en el nodo raíz (una técnica que utiliza jQuery Live). Para manejar también eventos personalizados que pueden no estar relacionados con DOM, puede usar un objeto antiguo de JavaScript simple para hacer el trabajo. Escribí un blog post sobre cómo crear un despachador central de eventos en MooTools con solo una línea de código.

var EventBus = new Class({Implements: Events}); 

Es igual de fácil de hacer en jQuery también. Use un objeto regular de JavaScript que actúe como intermediario central para todos los eventos. Cualquier objeto cliente puede publicar y suscribirse a eventos en este objeto. Consulte esto relacionado question.

var EventManager = { 
    subscribe: function(event, fn) { 
     $(this).bind(event, fn); 
    }, 
    unsubscribe: function(event, fn) { 
     $(this).unbind(event, fn); 
    }, 
    publish: function(event) { 
     $(this).trigger(event); 
    } 
}; 

// Your code can publish and subscribe to events as: 
EventManager.subscribe("tabClicked", function() { 
    // do something 
}); 

EventManager.publish("tabClicked"); 

EventManager.unsubscribe("tabClicked"); 

O si no se preocupan por la exposición de jQuery, a continuación, sólo tiene que utilizar un objeto vacío y llamarlo bind y trigger directamente en el jQuery envuelto objeto.

var EventManager = {}; 

$(EventManager).bind("tabClicked", function() { 
    // do something 
}); 

$(EventManager).trigger("tabClicked"); 

$(EventManager).unbind("tabClicked"); 

Las envolturas son simplemente hay que ocultar la biblioteca jQuery subyacente para que pueda reemplazar la implementación más adelante, si es necesario.

Este es básicamente el Publish/Subscribe o la Observer pattern, y algunos buenos ejemplos sería la clase de cacao NSNotificationCenter, EventBus patrón popularizado por Ray Ryan en la comunidad GWT, y varios otros.

+0

La solución https://gist.github.com/786386 es similar, pero admite la cancelación de la suscripción mediante tokens. La solución http://stackoverflow.com/a/2969692/873282 es aún más avanzada y también admite la cancelación de suscripción (pasando la referencia a la función) – koppor

+0

@koppor: Su segundo enlace apunta a * esta * respuesta. Seguramente te estabas refiriendo a algo más? – Aaronaught

+0

No recuerdo a qué otra URL podría haber querido referirme. Tal vez, quería apuntar a https://github.com/cujojs/msgs o https://github.com/sissbruecker/js-event-bus? – koppor

2

realidad, hay dos de ellos:

+0

¡Agradable! ¡Gracias, jefe! He estado buscando este tipo de funcionalidad en JS durante mucho tiempo. – leeand00

+0

en realidad me sorprendió que JQuery necesite complementos para eso. Normalmente uso Prototype y ahí está la forma predeterminada de hacerlo. – vartec

+0

Espera tal vez fui demasiado apresurado al aceptar esto como la respuesta. Los revisé, y ninguna de esas bibliotecas parece tener un componente central en el que se disparan los eventos y se notifica a los suscriptores. – leeand00

1

He usado OpenAjax Hub para sus servicios de publicación/suscripción. No es un complemento de jQuery, sino un módulo de JavaScript independiente. Puede descargar y usar el reference implementation de SourceForge. Me gusta la nomenclatura jerárquica de temas y el soporte para suscribirse a múltiples temas utilizando la notación comodín.

2

¿Podría esto servir como un marco de aprobación de mensaje liviano?

function MyConstructor() { 
    this.MessageQueues = {}; 

    this.PostMessage = function (Subject) { 
     var Queue = this.MessageQueues[Subject]; 
     if (Queue) return function() { 
             var i = Queue.length - 1; 
             do Queue[i](); 
             while (i--); 
            } 
     } 

    this.Listen = function (Subject, Listener) { 
     var Queue = this.MessageQueues[Subject] || []; 
     (this.MessageQueues[Subject] = Queue).push(Listener); 
    } 
} 

entonces se podría hacer:

var myInstance = new MyConstructor(); 
myInstance.Listen("some message", callback()); 
myInstance.Listen("some other message", anotherCallback()); 
myInstance.Listen("some message", yesAnotherCallback()); 

y posterior:

myInstance.PostMessage("some message"); 

enviaría las colas

2

Esta facilidad se puede lograr usando un nodo jQuery ficticia como despachador :

var someModule = (function ($) { 

    var dispatcher = $("<div>"); 

    function init() { 
     _doSomething(); 
    } 

    /** 
     @private 
    */ 
    function _doSomething() { 
     dispatcher.triggerHandler("SOME_CUSTOM_EVENT", [{someEventProperty: 1337}]); 
    } 

    return { 
     dispatcher: dispatcher, 
     init: init 
    } 

}(jQuery)); 



var someOtherModule = (function ($) { 

    function init() { 
     someModule.dispatcher.bind("SOME_CUSTOM_EVENT", _handleSomeEvent) 
    } 

    /** 
     @private 
    */ 
    function _handleSomeEvent (e, extra) { 
     console.log(extra.someEventProperty) //1337 
    } 

    return { 
     init: init 
    } 

}(jQuery)); 

$(function() { 
    someOtherModule.init(); 
    someModule.init(); 
}) 
+0

+1 Me gusta la idea de confiar en las técnicas dom conocidas sin alterar la dom –

5

Aunque no es un complemento jQuery, Twitter lanzó un marco de JavaScript llamado Flight que le permite crear arquitecturas basadas en componentes, que se comunican a través de eventos.

Flight es un marco de JavaScript ligero basado en componentes de Twitter. A diferencia de otros marcos de JavaScript que se basan en el patrón MVC, Flight asigna el comportamiento directamente a los nodos DOM.

Flight es independiente de cómo se enrutan las solicitudes o qué biblioteca de plantillas decide utilizar. Flight aplica estricta separación de preocupaciones. Los componentes en vuelo no se atacan entre sí directamente.

Transmiten sus acciones como eventos y los componentes suscritos a esos eventos pueden tomar acciones basadas en ellos. Para utilizar Flight, necesitará ES5-shim y jQuery junto con un cargador AMD.

Flight - A Lightweight, Component-Based JavaScript Framework From Twitter

2

Un desarrollo reciente es "programación orientada Mensaje JavaScript. Inspirado por la integración de la primavera" msgs.js.También es compatible con la comunicación a través de WebSockets.

msgs.js aplica el vocabulario y los patrones definidos en el libro 'Enterprise Integration Patterns' a JavaScript, ampliando la programación orientada a la mensajería en el navegador y/o el lado del servidor JavaScript. Los patrones de mensajería originalmente desarrollados para integrar sistemas dispares débilmente acoplados, se aplican igual de bien a módulos acoplados débilmente dentro de un solo proceso de aplicación.

[...]

entornos probados:

  • Node.js (0.6, 0.8)
  • Chrome (estable)
  • Firefox (estable, ESR, debería trabajar en principios versiones)
  • IE (6-10)
  • Safari (5, 6, iOS 4-6, deben trabajar en versiones anteriores)
  • Opera (11, 12, debería funcionar en versiones anteriores)