2015-12-22 25 views
8

Pracuję nad dynamiczną stroną internetową. W głównej formie mam wiele podformuł, które można dodawać i usuwać dynamicznie.Oczekiwanie na wszystkie wywołania AJAX niż wyświetlanie okna dialogowego

<div class='subform'> 
    //form fields 
    <input ...> 
    ... 
    <button class='subform_submit'> 
</div> 

Dla każdego podformularzu, wiążę wywołanie AJAX na przycisk Prześlij podformularzu jest tak:

$('#main').on('click', '.subform_submit', function(){ 
    // Get this subform's user input 
    ... 
    $.ajax({ 
     url: .., 
     type: .., 
     data: /* this subform's data */ 
    }); 
}); 

Więc w tej stronie, mogę mieć od 0 do 10 podformularze w zależności od wyboru użytkownika. Mam również główny przycisk przesyłania na dole strony, który może przesłać te podformy i dane głównego formularza razem.

$('#main').on('click', '#submit', function(e){ 
    $('.subform_submit').click(); // Submit each subform 
    bootbox.confirm({ }); 
}) 

Gdy przycisk główny złożyć kliknięciu, chcę pokazać obraz ładowania, a następnie wyświetlić okno dialogowe (używam bootbox.confirm() tutaj), aż wszystkie wywołania AJAX zakończyły. To okno dialogowe informuje użytkownika, że ​​został przesłany cały formularz zawierający podformy. Ale problem polega na tym, że każde wywołanie AJAX może zająć 2 sekundy i nie wiem, jak połączenia mogą być oczekujące na zakończenie. Jak mogę napisać to główny przycisk Prześlij tak, że będzie:

  1. Pokaż loading image natychmiast, a
  2. Ukryj loading image i pokazać okno dialogowe po wszystkie wywołania AJAX zakończeniu?
+0

Dzięki za @Lewis najlepsze rozwiązanie! – monknom

Odpowiedz

2

Chcesz użyć .done() w celu określenia kodu, który powinien poczekać, aż zakończy się funkcja asynchroniczna AJAX.

$.ajax({ 
    url:.., 
    type: .., 
    data: /* this subform's data*/ }) 
    .done(function() { 
     //Put code here 
    }); 
1

Czy próbowałeś już .ajaxStop() event handler?

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

również sprawdzić this answer

4

Śledzić ile cząstkowe postacie istnieją;

$subFormsCount = $('.subform').length; 

Śledź liczbę złożonych formularzy;

$submittedForms = 0; 

Za każdym razem, gdy formularz się kończy, dodaj do $ submittedForms;

$.ajax({ 
    .. 
    .. 
    done: function(){ 
    $submittedForms++; 
    } 
}) 

Utwórz globalny licznik czasu, aby sprawdzić, czy liczba przesłanych formularzy jest zgodna z całkowitą liczbą podformuł. Jeśli true, ukryj okno dialogowe;

setInterval(function(){ 
    if($submittedForms == $subFormsCount){ 
    $('.dialog').show(); 
    } 
}, 50ms) 

Edit

Można pominąć globalny licznik (jak będzie to prawdopodobnie kilka milisekund out) - obejmuje sprawdzenie w swoim ajax.done zamiast;

$.ajax({ 
    .. 
    .. 
    done: function(){ 
    $submittedForms++; 

    if($submittedForms == $subFormsCount){ 
    $('.dialog').show(); 
    } 
    } 
}) 
+0

gdzie należy umieścić kod okna dialogowego? Jeśli zaznaczysz w ajax.done, co jeśli istnieje 0 podform i nadal chcę zobaczyć okno dialogowe? – monknom

+0

@monknom Nie jestem pewien, o co pytasz. Myślałem, że chcesz pokazać obraz podczas składania podformularzy i okno dialogowe dopiero po ich zakończeniu? – Lewis

+0

Przykro mi z powodu mojego słabego angielskiego, obraz jest przeznaczony do przesyłania podform. ale okno dialogowe chcę powiedzieć ludziom, że cała forma została przesłana nie tylko podformularz – monknom

0

Zakładam, że masz 9 podformuł i 1 główny formularz. Kod dla 8 podformuł będzie taki sam.

Używam tutaj async: false: Oznacza, że ​​następny ajax nie zostanie wywołany, dopóki 1 nie zostanie zakończony. Kod

Przykładowy format:

var id = 5; 
$.ajax({ 
    url: , 
    type: 'POST', 
    data: {'id':id}, 
    dataType: 'JSON', 
    async: false, 
    error : function(xhr, textStatus, errorThrown) { 
     alert('An error occurred!'); 
    }, 
    success : function(response){ 

    } 
}); 

Wystarczy ustawić zmienną w ostatniej postaci sub czyli 9-ci podformularz.

success : function(response){ 
     var counter = true; 
    } 

if(counter){ 
    /* Code to show dialog.*/ 
} 
0

Można użyć $.when czekać na każde żądanie, aby zakończyć. Coś takiego powinno cię do siebie zbliżyć. Zasadniczo chcesz przechowywać wszystkie żądania ajax w tablicy i przekazać je jako when jako argumenty.

$('#main').on('click', '.subform_submit', function() { 

    var formRequests = $('.subform').map(function() { 
    var $form = $(this); 
    return $.ajax({ 
     url: '', 
     data: $form.serialzeArray() 
    }); 
    }).get(); 

    $.when.apply(undefined, formRequests).done(function() { 
    console.log('All done!'); 
    }); 

}); 

Tu idzie bardzo podobny trochę demo po prostu składa się: https://jsfiddle.net/g9a06y4t/