2009-11-04 6 views
5

Ich führe eine Validierung von Formulardaten durch, so dass, wenn jemand die Übermittlungsschaltfläche drückt, zuerst der Inhalt des Formulars überprüft wird. Eine Anzahl von Feldern (könnte null sein, könnte mehr als eins sein, abhängig von der Seite) hat Dinge wie eindeutige Codes, die zuerst mit dem Server überprüft werden müssen. Ich führe eine asynchrone Anfrage an den Server, der einfach für jedes Feld 'ok' oder 'taken' antwortet. Wenn eines der Felder Fehler aufweist, wird die Seite nicht gesendet.jQuery AJAX: Sammeln mehrerer asynchroner Ergebnisse

Auf der einen Seite sollte dies asynchron sein: Es sollte weiterhin die restlichen Formularfelder validieren, während diese Anfrage aus ist, einschließlich der Abarbeitung anderer Anfragen. Wenn der Aufruf synchron erfolgt, wird die Rückmeldung bei späteren Feldern sichtbar verlangsamt.

Auf der anderen Seite möchte ich alle, um sicherzustellen, hat zurückzuValidierungsAnforderungen (oder Zeitüberschreitung), bevor mit ja oder nein zu dem validate() Verfahren reagiert und entweder so dass die fortzufahren oder nicht vorlegen. Wenn also zwei Felder validiert werden müssen, sollte die Methode diese beiden AJAX-Anforderungen auslösen, die restlichen Felder verarbeiten und dann warten, bis diese beiden Anforderungen zurückgegeben wurden, bevor sie schließlich zurückgegeben werden.

Ich kann dies wahrscheinlich mit einigen hässlichen homebaked Lösung erreichen (wahrscheinlich mit einem Array von zufälligen IDs die Anforderungen in Bearbeitung oder etwas), aber bevor ich es tun, gibt es eine eingebaute Funktion, Plugin oder Standard-Technik sollte ich sein stattdessen verwenden?


Klärung

Was ich glaube, ich brauche den Code Warten auf das Ergebnis von einem oder mehreren asynchronen Anforderungen, bevor Sie mit einer Methode zu machen. Dies ist nicht dasselbe wie ein Callback, da das Ergebnis der Methode vom Ergebnis der Anfragen abhängt. Es ist nicht dasselbe wie eine synchrone Anfrage, weil es mehr als eine von ihnen geben kann.

Ich verwende dies die Form zu überprüfen, bevor die Einreichung:

$("form").submit(function() { 
    return validate($(this)); 
}); 

Wenn die validate() Methode false zurückgibt, dann wird das Formular nicht. validate() hilights alle Felder, die nicht akzeptiert werden. Für normale Felder, sieht validate() so etwas wie diese (stark vereinfachte Version ohne Feedback):

function validate(form) { 
    resetWarnings(form); 
    var ok = true; 

    // required fields 
    form.find("input.required").each(function() { 
     var field = $(this); 
     if (field.val() === "") { 
      ok = false; 
     } 
     return this; // meaningless in this case but a good habit to keep 
    }); 

    // fields that matches a pattern 
    form.find("input.pattern").each(function() { 
     var field = $(this); 
     var pattern = field.data("pattern"); 
     if (!field.val().match(pattern)) { 
      ok = false; 
     } 
     return this; 
    }); 

    // various other rules for other sorts of field 
    ... 

    return ok; 
} 

für AJAX Felder, es ist mehr wie folgt aus:

form.find("input.lookup").each(function() { 
     var field = $(this); 
     var url = field.data("lookup"); 
     $.ajax({ 
      url: url, 
      data: { code: field.val() }, 
      success: function (result) { 
       if (result === "taken") { 
        ok = false; 
       } 
      } 
     } 
    }); 

Aber natürlich hat validate() schon fertig vor Die Erfolgsmethode wird aufgerufen. Wenn ich also warten kann, bis der Ajax abgeschlossen ist (entweder Erfolg oder Fehler), bevor ich zurückkomme, kann ich das richtige Ergebnis erhalten und das Übermitteln des Formulars stoppen. Und wenn ich den Ajax synchron mache, stoppt die gesamte Methode, bis sie fertig ist, was falsch ist.


dachte Weitere

Da Javascript des Threading-Modell (die keiner zu sagen, überhaupt ist), ist das, was ich für technisch unmöglich bin gefragt?

Antwort

1

Wenn ich Sie richtig verstehe, wollen Sie überprüfen, dass die Werte (1 ..*), die in einem Formular eingegeben werden, sind einmalig, sobald der Benutzer die Schaltfläche "Senden" betätigt, bevor er den Beitrag auf dem Formular ausführt. Wenn das der Fall ist, würde ich ein JSON-Array von Feldern und Werten erstellen und alles auf einmal senden - so warten Sie nur auf eine Antwort. Dies sollte ziemlich einfach sein mit der jQuery 'each' Funktion und mit jQuery ajax.

Sie können das einzelne Ergebnis vor dem Senden des Formulars überprüfen.

Es ist wahrscheinlich eine Selbstverständlichkeit, aber stellen Sie sicher, dass Sie die gleiche Validierung serverseitig wiederholen, sobald Sie gepostet haben, um mit anderen Benutzern Race Conditions zu vermeiden. Wenn Sie das Formular ausfüllen und das Ergebnis speichern, können Sie einzelne Felder validieren. Dies wäre jedoch deutlich gesprächiger (aus Gründen der Skalierbarkeit sollten Sie die Bandbreite in Betracht ziehen), und Sie riskieren, dass die serverseitige Validierung fehlschlägt .

+0

Es ist keine Folge identischer eindeutiger Felder, aber die Möglichkeit, dass mehr als ein Feld in einem Formular serverseitig überprüft werden muss - bei verschiedenen URLs, gegen verschiedene Prüfungen. In der Tat ist das Mehrfachbit nicht das, was wichtig ist - es lässt die validate() - Methode auf ein asynchrones Ergebnis warten. Der einzige Grund, warum ich betone, dass es mehr als ein Feld gibt, ist, dass ein synchroner Aufruf keine gültige Antwort ist. –

+0

Siehe Erläuterung. –

+0

Ich bin mir nicht sicher, wonach ich frage, ist möglich. Das Überprüfen der Felder, wenn der Benutzer das Formular ausfüllt, ist möglicherweise der einzige Weg. –

0

Wie wäre es mit .ajaxStop:

$(document).ajaxStop(function() { 
    $(this).unbind("ajaxStop"); 
    // run validate method here 
    }); 
    //run asynchronous validations here 

Hinweis, die benötigt UNBIND, wenn validate() selbst einen AJAX-Aufruf beinhaltet.

3

Mit jQuery 1.5+ besteht die beste Möglichkeit zum Sammeln von Ergebnisdaten aus mehreren asynchronen Anforderungen in der Verwendung von verzögerten Objekten, die diese Anforderungen mit ihren Zuständen darstellen, und der Wrapperfunktion $ .when (...). Then (allRequestsCompleteCallback()) someRequestFailedCallback())

Das hilft, die Verwendung mehrerer verschachtelter Callback-Funktionen zu vermeiden, die Ihren Code viel sauberer und einfacher zu pflegen machen.

JavaScript/jQuery Beispiel:

function ajax1() { return $.ajax({ url: 'server1.php' }) } 
function ajax2() { return $.ajax({ url: 'server2.php' }) } 

$.when(ajax1(), ajax2()).then(
    function() { 
     // ajax1 AND ajax2 succeeded 
    }, 
    function() { 
     // ajax1 OR ajax2 succeeded 
    } 
); 

prüfen, um weitere Dokumente und Beispiele hier:

+0

Gibt es eine Möglichkeit, dies zu tun, ohne im Voraus zu wissen, wie viele verzögerte Objekte Sie haben werden? Zum Beispiel, wenn die Mehrfachanforderungen darauf zurückzuführen sind, dass ein großes Array unbekannter Länge in Stücke konstanter Länge aufgeteilt wird? – learn2day

Verwandte Themen