Erfahren Sie, wann alle Ajax-Aufrufe abgeschlossen sind

75

Ich habe eine Seite im Tabellenstil mit Zeilen. Jede Zeile hat ein Kontrollkästchen. Ich kann alle / viele Kontrollkästchen aktivieren und auf "Senden" klicken. Für jede Zeile wird ein Jquery-Ajax-Aufruf ausgeführt.

Grundsätzlich habe ich ein Formular für jede Zeile und ich iteriere über alle markierten Zeilen und sende das Formular, das den jquery ajax-Aufruf ausführt.

Ich habe also einen Knopf, der Folgendes bewirkt:

       $("input:checked").parent("form").submit();

Dann hat jede Zeile:

            <form name="MyForm<%=i%>" action="javascript:processRow(<%=i%>)" method="post" style="margin:0px;">
                <input type="checkbox" name="X" value="XChecked"/>
                <input type="hidden" id="XNumber<%=i%>" name="X<%=i%>" value="<%=XNumber%>"/>
                <input type="hidden" id="XId<%=i%>" name="XId<%=i%>" value="<%=XNumber%>"/>
                <input type="hidden" id="XAmt<%=i%>" name="XAmt<%=i%>" value="<%=XAmount%>"/>
                <input type="hidden" name="X" value="rXChecked"/>
            </form>

Dieses Formular wird an processRow gesendet:

   function processRow(rowNum)
   {
        var Amount = $('#XAmt'+rowNum).val();
        var XId = $('#XId'+rowNum).val();
        var XNum = $('#OrderNumber'+rowNum).val();
        var queryString = "xAmt=" + "1.00" + "&xNumber=" + OrdNum + "&xId=" + xId;


        $('#coda_'+rowNum).removeClass("loader");
        $('#coda_'+rowNum).addClass("loading");


        $.ajax({
          url: "x.asp",
          cache: false,
          type:  "POST",
          data:  queryString,
          success: function(html){
            $('#result_'+rowNum).empty().append(html);
            $('#coda_'+rowNum).removeClass("loading");
            $('#coda_'+rowNum).addClass("loader");
          }
        });
   }

Was ich wissen wollte, ist, dass ich auf diese Weise feststellen kann, ob alle meine Ajax-Anrufe abgeschlossen sind. Grund dafür ist, dass Sie die Senden-Schaltfläche aktivieren / deaktivieren möchten, während all diese Anrufe stattfinden.

Vielen Dank und bitte beachten Sie, dass ich meine Variablennamen aufgrund der Empfindlichkeit der Anwendung entstellen musste, sodass viele davon möglicherweise dupliziert werden.

Brian G.
quelle
1
Obwohl das Erkennen, wann alle Ajax-Aufrufe abgeschlossen sind, für jedes Design von Wert ist, besteht meiner Meinung nach eine bessere Gesamtlösung darin, mehrere Zeilen gleichzeitig zu senden. Sende jede Zeile als separates Ajax Beitrag sein wird , wirklich hart in gewisser Weise auf dem System und ist nicht (meiner Meinung nach ) das beste Design. Ich werde sogar so weit gehen zu sagen, dass ich verspreche, dass Sie es eines Tages bereuen werden, wenn Sie sich an dieses Design von einem Ajax-Anruf pro Zeile halten.
ErikE
Abgesehen von dem Designproblem, auf das @ErikE hingewiesen hat, bin ich überrascht, dass niemand die Verwendung von Promises zur Beantwortung der ursprünglichen Frage erwähnt hat.
Delphi.Boy

Antworten:

139

Der einfache Weg

Der einfachste Weg ist die Verwendung des .ajaxStop()Ereignishandlers :

$(document).ajaxStop(function() {
  // place code to be executed on completion of last outstanding ajax call here
});

Der harte Weg

Sie können auch manuell erkennen, ob ein Ajax-Anruf noch aktiv ist:

Erstellen Sie eine Variable mit der Anzahl der aktiven Ajax-Verbindungen:

var activeAjaxConnections = 0;

Inkrementieren Sie diese Variable kurz vor dem Öffnen einer neuen Ajax-Verbindung

$.ajax({
  beforeSend: function(xhr) {
    activeAjaxConnections++;
  },
  url (...)

in successTeil zu überprüfen , ob diese Variable gleich Null ist (wenn ja, hat die letzte Verbindung beendet)

success: function(html){
  activeAjaxConnections--;
  $('#result_'+rowNum).empty().append(html);
  $('#coda_'+rowNum).removeClass("loading");
  $('#coda_'+rowNum).addClass("loader");
  if (0 == activeAjaxConnections) {
    // this was the last Ajax connection, do the thing
  }
},
error: function(xhr, errDesc, exception) {
  activeAjaxConnections--;
  if (0 == activeAjaxConnections) {
    // this was the last Ajax connection, do the thing
  }
}

Wie Sie sehen können, habe ich auch die Überprüfung auf Rückgabe mit Fehler hinzugefügt

Tomasz Tybulewicz
quelle
4
Wie können Sie den ajaxStop-Handler nach dem Auslösen wieder entfernen?
Rob
3
In Bezug auf 'The Hard way': Es ist nicht erforderlich, eine Variable zu verwalten. Jquery führt dies bereits aus: $ .active behält die aktuelle Anzahl aktiver Ajax-Aufrufe bei
Sebastianb
1
Hinweis vor dem Senden sollte vor dem Senden sein
Dean
Gibt es eine Möglichkeit herauszufinden, welcher Ajax-Aufruf es war, wenn mehrere gleichzeitig vorhanden waren?
Si8
23

Eine saubere Lösung wäre zu verwenden;

$("body").ajaxStop(function() {
    //Your code
});

Weitere Informationen finden Sie in der Funktion jQuery .ajaxStop unter http://api.jquery.com/ajaxStop/.

Tebo
quelle
-4

Wie wäre es einfach einfach wenn ?

success: function(html){
   if(html.success == true ){
            $('#result_'+rowNum).empty().append(html);
            $('#coda_'+rowNum).removeClass("loading");
            $('#coda_'+rowNum).addClass("loader");

          }
   }
Jarda
quelle