¿Cuándo usaría JQuery.Callbacks?
jquery-callback jquery-1.7 (6)
Un (casi) fuera de la caja jQuery Pub / Sub system
Esta es, en mi humilde opinión, la aplicación más interesante, y como no estaba claramente indicada en las respuestas (aunque algunos hacen alusión al uso), la estoy agregando a esta publicación relativamente antigua.
NB: el uso está claramente indicado, con un ejemplo, en los documentos de jQuery , pero creo que se agregó después de que se publicó la pregunta.
Pub/sub , también conocido como patrón de observador , es un patrón que promueve el acoplamiento flexible y la responsabilidad única en una aplicación. En lugar de tener objetos que llamen directamente a los métodos de otros objetos, los objetos se suscriben a una tarea o actividad específica y se notifican cuando ocurre. Para una explicación más detallada de los beneficios de usar el patrón Pub / Sub, puede verificar ¿Por qué usaría uno el patrón Publish / Subscribe (en JS / jQuery)? .
Claro, esto fue posible con eventos personalizados usando trigger
, .on()
y .off()
, pero encuentro que jQuery.Callbacks
es mucho más adecuado para la tarea, produciendo un código más limpio.
Aquí está el fragmento de ejemplo de la documentación de jQuery :
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;
};
Y un ejemplo de uso:
// Subscribers
$.Topic( "mailArrived" ).subscribe( fn1 );
$.Topic( "mailArrived" ).subscribe( fn2 );
$.Topic( "mailSent" ).subscribe( fn1 );
// Publisher
$.Topic( "mailArrived" ).publish( "hello world!" );
$.Topic( "mailSent" ).publish( "woo! mail!" );
// Here, "hello world!" gets pushed to fn1 and fn2
// when the "mailArrived" notification is published
// with "woo! mail!" also being pushed to fn1 when
// the "mailSent" notification is published.
/*
output:
hello world!
fn2 says: hello world!
woo! mail!
*/
Estaba revisando cosas nuevas agregadas a jQuery 1.7 y vi que ahora tienen jQuery.Callbacks () http://api.jquery.com/jQuery.Callbacks/ .
La documentación muestra cómo usar jQuery.callbacks () pero no ejemplos aplicables de cuándo me gustaría usarlos.
Parece que puedes agregar / eliminar devoluciones de llamada de una lista de devoluciones de llamada y puedes hacer jQuery.callbacks (). Fire (args), pero esto solo activa TODAS las devoluciones de llamada en esa lista. Tal vez me estoy perdiendo algo, pero esto no parece muy útil.
En mi cabeza cuando vi por primera vez esta nueva funcionalidad, pensé que podrías usarla con pares clave / valor. Que luego proporcionaría una forma simple de administrar funciones de devolución de llamada en un solo lugar en su aplicación. Algo como
$.callbacks.add("foo", myFunction);
y luego, por ejemplo, si quería llamar a esa devolución de llamada al final de mi función, podría hacer algo como
$.callbacks().fire("foo", args);
Sin embargo, no parece que pueda lanzar devoluciones de llamadas específicas, solo puede disparar a todas ellas con los argumentos dados o ninguna de ellas.
Lo más cercano que vi fue que se le dio la capacidad de darle a la función .fire () un contexto para establecer la propiedad "this"
.fireWith(context, args)
pero esto tampoco ayuda mucho.
¿Estoy malentendiendo la documentación?
Si esta es la funcionalidad deseada, ¿cuáles son algunos ejemplos aplicables donde esto es útil?
Estoy trabajando en una aplicación con mucha lógica empresarial y al menos 11 servicios externos. Realmente ayuda a mantener las cosas claras si puede escribir sus propias clases y comportamientos de control de flujo utilizando algo así como retrollamadas en lugar de tratar de forzar su voluntad en la implementación Diferida.
No veo ninguna mención específica de configuración de contexto, pero ya que puede pasar una cantidad arbitraria de argumentos, eso sería potencialmente útil. También podría hacer su propia convención para pasar una bandera como primer argumento y hacer que los oyentes devuelvan falso inmediatamente si no están destinados a manejar la lista de argumentos restantes.
He encontrado casos en los que algo como esto podría haber sido útil, pero en su lugar he usado bind () y trigger () con eventos personalizados. Imagine un sistema de manejo de mensajes (una sala de chat basada en la web o un cliente de correo electrónico) donde está sondeando un servicio para recibir mensajes nuevos. Una función podría ser establecer un número en un tramo o mostrar un gruñido cuando algo sucede. Otro podría estar actualizando una grilla. Con los desencadenantes tendría que desencadenar el evento para cada oyente y "desenrollar" los argumentos pasados de eventData, con devoluciones de llamadas es solo un incendio y sus oyentes son simples funciones de JavaScript con una simple lista de argumentos.
Las devoluciones de llamada no son exactamente revolucionarias, pero generarán menos y un código más limpio.
Para expandir en @Rockets, responde un poco y despeja la confusión:
La razón por la que uno podría necesitar usar $.Callbacks
jQuery es multifacético:
- El usuario tiene un montón de código en una función y quiere dividirlo
Toman esa información y la envían a través de la función de devolución de llamada de jQuery, que les permite dividir su código en piezas más manejables con las que trabajar.
Entonces (por ejemplo) si miras el código de @ Rocket :var clickCallbacks = $.Callbacks(); clickCallbacks.add(function() { //one one function piece //parse and do something on the scope of `this` var c = parseInt(this.text(), 10); this.text(c + 1); }); clickCallbacks.add(function(id) { //add a second non-related function piece //do something with the arguments that were passed $(''span'', ''#last'').text(id); }); $(''.click'').click(function() { var $ele = $(this).next(''div'').find(''[id^="clickCount"]''); clickCallbacks.fireWith($ele, [this.id]); //do two separate but related things. });
- Lo que ahora puede tener es varios lotes de funciones de devolución de llamada que ahora puede llamar cuando lo considere necesario sin la necesidad de realizar tantos cambios en todo su código.
Parece que $.Callbacks
comenzó como un detalle de implementación: un medio para administrar listas de funciones y llamar a todas las funciones en una lista dada con los mismos argumentos. Un poco como los delegados de multidifusión de C #, con características adicionales, como las banderas que puedes pasar para personalizar el comportamiento de la lista.
Un buen ejemplo podría ser que jQuery usa $.Callbacks
internamente para implementar su evento ready
. bindReady()
inicializa una lista de devolución de llamada:
readyList = jQuery.Callbacks( "once memory" );
Tenga en cuenta los indicadores de once
y de memory
, que aseguran que la lista de devolución de llamada solo se invoque una vez, y que las funciones añadidas después de que se haya llamado a la lista se invoquen inmediatamente.
Entonces, ready()
agrega el controlador especificado a esa lista:
ready: function( fn ) {
// Attach the listeners
jQuery.bindReady();
// Add the callback
readyList.add( fn );
return this;
}
Finalmente, la lista de devolución de llamada se activa cuando el DOM está listo:
readyList.fireWith( document, [ jQuery ] );
Todos los controladores ready
invocan en el contexto del mismo documento con la misma referencia al objeto jQuery global. Solo se pueden llamar así una vez, y los controladores adicionales pasados a ready()
se $.Callbacks
inmediatamente a partir de ese momento, todo esto por cortesía de $.Callbacks
.
Puedo ver que las devoluciones de llamadas son útiles cuando se actualizan diferentes elementos de DOM utilizando el mismo método (s).
Aquí hay un ejemplo cursi: http://jsfiddle.net/UX5Ln/
var clickCallbacks = $.Callbacks();
clickCallbacks.add(function() {
var c = parseInt(this.text(), 10);
this.text(c + 1);
});
clickCallbacks.add(function(id) {
$(''span'', ''#last'').text(id);
});
$(''.click'').click(function() {
var $ele = $(this).next(''div'').find(''[id^="clickCount"]'');
clickCallbacks.fireWith($ele, [this.id]);
});
Actualiza el contador de clics y el "último clic" al hacer clic en algo.