2010-10-13 19 views
5

Witam Mam ogromny problem, który podsłuchiwał mnie przez dłuższy czas, przez większość czasu byłem w stanie tego uniknąć, ale teraz nie ma innego sposobu. Poniżej znajduje się funkcja, która po uruchomieniu wysyła żądanie postu dla każdego zaznaczonego pola. Muszę czekać, aż $ .each skończy się, aby odświeżyć stronę. Przeprowadziłem testy z location.reload w wywołaniu zwrotnym każdego i poza każdym z nich. Z 10 wybranych skrzynek przetwarzane są tylko 7-8 z ponownym doładowaniem w wywołaniach $ .each i 3-4 po przesunięciu po $ .each (nadal wewnątrz .click). Potrzebuję go, aby jakoś poczekać na $ .each, aby zakończyć, a następnie odświeżyć stronę. Czy jest jakiś sposób na zrobienie tego?

$('button.moveToTable').click(function(event){ 
      $("input:checked").each(function(){ 
       $.post('/table/move-to-table', 
       {orderID: $(this).val(), 
        tableID: $('#moveToTableID').val() 
       }, 
       function(data){ 
        location.reload(); 
       }); 
      }); 
      //location.reload(); 
     }); 

Odpowiedz

6

Jednym prostym sposobem jest przechowywanie liczby elementów w zasięgu globalnym i odejmowanie ich. Kiedy ostatni element zakończy żądanie, przeładuje się. Zauważ, że jeśli jakieś żądanie zwróci błąd, to się nie powiedzie, musisz zająć się zdarzeniem błędu, a także odjąć window.Remaining. Dwa lub więcej kliknięć może również uszkodzić tę metodę.

window.Remaining = 0; 
$('button.moveToTable').click(function(event){ 
    window.Remaining = $("input:checked").length; 
    $("input:checked").each(function(){ 
     $.post('/table/move-to-table', 
     {orderID: $(this).val(), 
      tableID: $('#moveToTableID').val() 
     }, 
     function(data){ 
      --window.Remaining; 
      if (window.Remaining == 0) 
       window.location.reload(); 
     }); 
    }); 
    //location.reload(); 
}); 
+1

Niezły pomysł na użycie własności 'length'. Prawdopodobnie możesz uniknąć dwukrotnego uruchomienia selektora, wykonując coś w stylu 'window.Remaining = $ ('input: checked') each (function() {...}). Length'. : o) – user113716

+0

tylko jedna uwaga: dlaczego umieszczasz to pod "oknem"? To działałoby równie dobrze w zakresie lokalnym. nie trzeba zanieczyszczać globalnej przestrzeni nazw. –

5

Nie wiem, czy jest to najlepsze rozwiązanie, ale jeden pomysłem byłoby do zwiększania liczbę żądań wysyłanych do każdego z nich, a następnie zmniejszyć go jako żądania zwrotu.

Użyj liczby jako flagi, aby określić, czy należy odpalić reload().

coś takiego:

var count = 0; 

$('button.moveToTable').click(function(event){ 
      $("input:checked").each(function() { 
       count++; // Increment the counter for each request 

       $.post('/table/move-to-table', 
       {orderID: $(this).val(), 
        tableID: $('#moveToTableID').val() 
       }, 
       function(data) { 
        count--; // Decrement as the requests return 

         // Only reload if the count is 0 
        if(count === 0) 
         location.reload(); 
       }); 
      }); 
     }); 

powinny Prawdopodobnie masz jakiś kod, aby zapobiec występowaniu click z drugiego kliknięcia. Prawdopodobnie możesz użyć tej samej zmiennej count.

na przykład:

if(count === 0) { 
    $("input:checked").each(func... 

Albo lepszym pomysłem może być użycie this solution from nsw1475 i wysłać tylko jedną prośbę do wszystkich pól, jeśli ta opcja jest dostępna dla Ciebie.

2

Lepszym, wydajniejszym i wolniejszym od błędów sposobem może być użycie funkcji each() do wygenerowania tablicy json przechowującej zaznaczone pola wyboru, a następnie użycie .post do przekazania wszystkich danych razem . Po wykonaniu tej czynności odśwież stronę oddzwonienia.