web-dev-qa-db-fra.com

Quand utiliser JQuery.Callbacks?

Je cherchais de nouveaux éléments ajoutés à jQuery 1.7 et j’ai vu qu’ils avaient maintenant jQuery.Callbacks () http://api.jquery.com/jQuery.Callbacks/

La documentation vous montre comment utiliser jQuery.callbacks (), mais aucun exemple applicable de la date à laquelle je souhaite les utiliser.

Il semble que vous puissiez ajouter/supprimer des rappels dans une liste de rappel et jQuery.callbacks (). Fire (args), mais cela déclenche simplement TOUTES les rappels de cette liste. Peut-être me manque quelque chose mais cela ne semble pas très utile.

Dans ma tête, lorsque j'ai découvert cette nouvelle fonctionnalité, je pensais que vous seriez en mesure de l'utiliser avec des paires clé/valeur. Ce qui fournirait alors un moyen simple de gérer les fonctions de rappel à un seul endroit dans votre application. Quelque chose comme

$.callbacks.add("foo", myFunction);

et puis par exemple si je voulais appeler ce rappel à la fin de ma fonction, je pouvais faire quelque chose comme

$.callbacks().fire("foo", args);

Cependant, il ne semble pas que vous puissiez déclencher des rappels spécifiques, vous pouvez uniquement les envoyer avec les arguments donnés ou aucun d'entre eux.

La chose la plus proche que j'ai vue était la possibilité de donner à la fonction .fire () un contexte pour définir la propriété "this" 

.fireWith(context, args)

mais cela n'aide pas beaucoup non plus.

  1. Est-ce que je comprends mal la documentation?

  2. S'il s'agit de la fonctionnalité souhaitée, quels sont les exemples où cela est utile?

41
Keith.Abramo

Pour développer @Rockets répondre un peu et éclaircir une certaine confusion:

La raison pour laquelle on peut avoir besoin d'utiliser le $.Callbacks de jQuery est multiple:

  1. L'utilisateur a beaucoup de code dans une fonction et veut le séparer
  2. Ils prennent ces informations et les envoient via la fonction de rappel jQuery, ce qui leur permet ensuite de scinder leur code en éléments plus gérables avec lesquels travailler.
    Donc (par exemple) si vous regardez le code 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.
    });
    
  3. Ce que vous pouvez maintenant avoir, ce sont plusieurs lots de fonctions de rappel que vous pouvez maintenant appeler chaque fois que vous le jugerez nécessaire sans avoir à apporter autant de modifications tout au long de votre code.
16
Neal

Je peux voir que les rappels sont utiles lorsque vous mettez à jour différents éléments DOM en utilisant la même méthode.

Voici un exemple ringard: 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]);
});

Il met à jour le compteur de clics et le «dernier clic» lorsque vous cliquez sur quelque chose.

12
Rocket Hazmat

Un système (presque)} prêt à l'emploi jQuery Pub/Sub

C’est à mon humble avis l’application la plus intéressante, et comme il n’était pas indiqué {clairement} _ dans les réponses (bien que certains fassent allusion à cet usage), je l’ajoute à cet article relativement ancien. 

NB: L'usage est clairement indiqué, avec un exemple, dans jQuery docs , mais je suppose qu'il a été ajouté après la publication de la question.

Pub/sub , alias le motif observateur, est un motif qui favorise couplage lâche et responsabilité unique dans une application. Plutôt que d'avoir des objets appelant directement les méthodes d'autres objets, les objets s'abonnent plutôt à une tâche ou à une activité spécifique et sont avertis de son exécution. Pour une explication plus détaillée des avantages de l'utilisation du modèle Pub/Sous, vous pouvez vérifier Pourquoi utiliser le modèle Publier/S'abonner (dans JS/jQuery)? .

Bien sûr, cela a été possible avec les événements personnalisés en utilisant trigger, .on() et .off(), mais je trouve que jQuery.Callbacks est a beaucoup plus adapté à la tâche, produisant un code plus propre.

Voici l'extrait de code de la documentation 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;
};

Et un exemple d'utilisation:

// 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!
*/
8
edsioufi

Il semble que $.Callbacks ait commencé comme un détail d'implémentation: un moyen de gérer des listes de fonctions et d'appeler toutes les fonctions d'une liste donnée avec les mêmes arguments. Un peu comme C/s multicast delegues , avec des fonctionnalités supplémentaires, telles que les drapeaux que vous pouvez passer pour personnaliser le comportement de la liste.

Un bon exemple pourrait être que jQuery utilise $.Callbacks en interne pour implémenter son événement ready. bindReady() initialise une liste de rappel:

readyList = jQuery.Callbacks( "once memory" );

Notez les indicateurs once et memory, qui garantissent que la liste de rappel ne sera appelée qu'une seule fois, et que les fonctions ajoutées après l'appel de la liste seront appelées immédiatement.

Ensuite, ready() ajoute le gestionnaire spécifié à cette liste:

ready: function( fn ) {
    // Attach the listeners
    jQuery.bindReady();

    // Add the callback
    readyList.add( fn );

    return this;
}

Enfin, la liste de rappel est déclenchée lorsque le DOM est prêt:

readyList.fireWith( document, [ jQuery ] );

Tous les gestionnaires ready sont appelés dans le contexte du même document avec la même référence à l'objet global jQuery. Ils ne peuvent être appelés que cette fois, et les gestionnaires supplémentaires passés à ready() seront immédiatement appelés, toute cette courtoisie de $.Callbacks.

3

Je ne vois aucune mention spécifique du contexte de réglage, mais puisque vous pouvez passer un nombre arbitraire d'arguments, cela pourrait être utile. Vous pouvez également créer votre propre convention pour passer un drapeau en tant que premier argument et demander aux écouteurs de renvoyer faux immédiatement s'ils ne sont pas censés gérer la liste d'arguments restante.

J'ai rencontré des cas où quelque chose comme cela aurait pu être utile, mais j'ai plutôt utilisé bind () et trigger () avec des événements personnalisés. Imaginez un système de messagerie (un forum de discussion ou un client de messagerie basé sur le Web) dans lequel vous interrogez un service pour obtenir de nouveaux messages. L'une des fonctions peut être de définir un nombre sur une période ou d'afficher un grondement lorsque quelque chose se produit. Une autre pourrait être la mise à jour d'une grille. Avec les déclencheurs, vous devez déclencher l'événement pour chaque écouteur et "dérouler" les arguments passés de eventData. Avec les rappels, il ne s'agit que d'un feu et vos écouteurs sont de simples fonctions javascript avec une simple liste d'arguments.

Les rappels ne sont pas vraiment révolutionnaires, mais cela réduira le code et le rendra plus propre.

2
flesk

Je travaille sur une application avec beaucoup de logique métier et au moins 11 services externes. Cela aide vraiment à garder les choses droites si vous pouvez écrire vos propres classes et comportements de contrôle de flux en utilisant quelque chose comme les rappels au lieu d'essayer d'imposer votre volonté à l'implémentation différée.

0
AutoSponge