webentwicklung-frage-antwort-db.com.de

Wann würde ich JQuery.Callbacks verwenden?

Ich habe in jQuery 1.7 neue Dinge durchgesehen und festgestellt, dass sie jetzt jQuery.Callbacks () http://api.jquery.com/jQuery.Callbacks/ enthalten.

Die Dokumentation zeigt Ihnen, wie Sie jQuery.callbacks () verwenden, aber keine anwendbaren Beispiele, wann ich sie verwenden möchte.

Sie können anscheinend Rückrufe zu einer Rückrufliste hinzufügen/daraus entfernen und jQuery.callbacks (). Fire (args) ausführen, dies löst jedoch ALLE Rückrufe in dieser Liste aus. Vielleicht fehlt mir etwas, aber das scheint nicht sehr nützlich zu sein.

Als ich diese neue Funktionalität zum ersten Mal sah, dachte ich, Sie könnten sie mit Schlüssel/Wert-Paaren verwenden. Auf diese Weise können Sie die Rückruffunktionen auf einfache Weise an einem einzigen Ort in Ihrer Anwendung verwalten. So etwas wie

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

und wenn ich dann zum Beispiel diesen Rückruf am Ende meiner Funktion aufrufen wollte, könnte ich so etwas tun

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

Es sieht jedoch nicht so aus, als könnten Sie bestimmte Rückrufe abfeuern. Sie können nur alle mit den angegebenen Argumenten oder keines von ihnen abfeuern.

Das Nächste, was ich sah, war die Möglichkeit, der .fire () - Funktion einen Kontext zu geben, um die "this" -Eigenschaft festzulegen

.fireWith(context, args)

aber das hilft auch nicht wirklich viel.

  1. Verstehe ich die Dokumentation falsch?

  2. Wenn dies die gewünschte Funktionalität ist, welche Beispiele sind anwendbar, wo dies nützlich ist.

41
Keith.Abramo

Um @Rockets answer etwas zu erweitern und einige Verwirrung zu beseitigen:

Der Grund, warum man den $.Callbacks von jQuery verwenden muss, ist vielfältig:

  1. Der Benutzer hat viel Code in einer Funktion und möchte ihn aufteilen
  2. Sie nehmen diese Informationen und senden sie über die jQuery-Callback-Funktion, die es ihnen ermöglicht, ihren Code in besser handhabbare Teile aufzuteilen, mit denen er arbeiten kann.
    Also (zum Beispiel), wenn Sie sich den @ Rockets Code ansehen:

    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. Sie können jetzt mehrere Callback-Stapel mit Funktionen aufrufen, die Sie jetzt aufrufen können, wenn Sie es für notwendig erachten, ohne dass Sie so viele Änderungen im gesamten Code vornehmen müssen.
16
Neal

Ich kann Rückrufe sehen, die nützlich sind, wenn Sie verschiedene DOM-Elemente mit denselben Methoden aktualisieren.

Hier ist ein kitschiges Beispiel: 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]);
});

Es aktualisiert den Klickzähler und den "zuletzt angeklickten", wenn Sie auf etwas klicken.

12
Rocket Hazmat

Ein (fast) out of the Box jQuery Pub/Sub-System

Dies ist meiner Meinung nach die interessanteste Anwendung, und da in den Antworten nicht eindeutig angegeben wurde (obwohl einige Anspielungen auf die Verwendung machen), füge ich es diesem relativ alten Beitrag hinzu. 

NB: Die Verwendung ist in den jQuery-Dokumenten mit einem Beispiel deutlich angegeben, aber ich denke, sie wurde hinzugefügt, nachdem die Frage gepostet wurde.

Pub/sub , alias das Beobachtermuster, ist ein Muster, das lose Kopplung und Einzelverantwortung in einer Anwendung fördert. Anstatt Objekte direkt die Methoden anderer Objekte aufzurufen, abonnieren Objekte stattdessen eine bestimmte Aufgabe oder Aktivität und werden benachrichtigt, wenn sie auftritt. Eine detailliertere Erklärung der Vorteile der Verwendung des Pub/Sub-Musters finden Sie unter Warum sollte man das Publish/Subscribe-Muster (in JS/jQuery) verwenden? .

Sicher, dies war mit benutzerdefinierten Ereignissen möglich mit trigger, .on() und .off(), aber ich finde, jQuery.Callbacks sei viel eher geeignet für die Aufgabe und produziere saubereren Code.

Hier ist der Beispielausschnitt aus der jQuery-Dokumentation :

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

Und ein Anwendungsbeispiel:

// 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

Es scheint, dass $.Callbacks als Implementierungsdetail begann: ein Mittel zum Verwalten von Funktionslisten und zum Aufrufen aller Funktionen in einer gegebenen Liste mit denselben Argumenten. Ein bisschen wie C # s Multicast-Delegaten , mit zusätzlichen Funktionen wie den Flags, die Sie übergeben können, um das Verhalten der Liste anzupassen.

Ein gutes Beispiel ist, dass jQuery intern $.Callbacks verwendet, um das Ereignis ready zu implementieren. bindReady() initialisiert eine Rückrufliste:

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

Beachten Sie die Flags once und memory, die sicherstellen, dass die Callback-Liste nur einmal aufgerufen wird, und dass Funktionen, die nach dem Aufruf der Liste hinzugefügt wurden, sofort aufgerufen werden.

Dann fügt ready() den angegebenen Handler dieser Liste hinzu:

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

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

    return this;
}

Schließlich wird die Rückrufliste ausgelöst, wenn das DOM bereit ist:

readyList.fireWith( document, [ jQuery ] );

Alle ready-Handler werden im Kontext desselben Dokuments mit demselben Verweis auf das globale jQuery-Objekt aufgerufen. Sie können dies nur einmal aufgerufen werden, und zusätzliche Handler, die an ready() übergeben werden, werden ab sofort sofort aufgerufen. All dies wird mit $.Callbacks zur Verfügung gestellt.

3

Ich kann den Einstellungskontext nicht ausdrücklich erwähnen, aber da Sie eine beliebige Anzahl von Argumenten übergeben können, wäre dies möglicherweise nützlich. Sie können auch Ihre eigene Konvention erstellen, um ein Flag als erstes Argument zu übergeben, und die Listener müssen sofort false zurückgeben, wenn sie die verbleibende Argumentliste nicht behandeln sollen.

Ich habe Fälle erlebt, in denen so etwas nützlich gewesen sein könnte, aber stattdessen bind () und trigger () mit benutzerdefinierten Ereignissen verwendet haben. Stellen Sie sich ein System zur Bearbeitung von Nachrichten (ein webbasierter Chatroom oder E-Mail-Client) vor, bei dem Sie einen Dienst nach neuen Nachrichten abfragen. Eine Funktion kann das Einstellen einer Zahl in einem Bereich oder das Anzeigen eines Knurrens sein, wenn etwas passiert. Ein anderes könnte ein Raster aktualisieren. Mit Triggern müssen Sie das Ereignis für jeden Listener auslösen und die übergebenen Argumente von eventData "abwickeln". Bei Rückrufen ist es nur ein Feuer und Ihre Listener sind einfache Javascript-Funktionen mit einer einfachen Argumentliste.

Callbacks ist zwar nicht gerade revolutionär, sorgt jedoch für weniger und saubereren Code.

2
flesk

Ich arbeite an einer App mit viel Geschäftslogik und mindestens 11 externen Services. Es hilft wirklich, die Dinge klar zu halten, wenn Sie Ihre eigenen Flow Control-Klassen und deren Verhalten mithilfe von Callbacks schreiben können, anstatt zu versuchen, Ihren Willen für die verzögerte Implementierung zu erzwingen.

0
AutoSponge