2010-10-13 12 views
5

Ciao, ho un grosso problema che mi turba da un po 'di tempo, il più delle volte sono stato in grado di evitarlo ma ora non c'è altro modo. Di seguito è riportata una funzione che, una volta eseguita, invia una richiesta di post per ogni casella selezionata. Ho bisogno di aspettare che $ .each abbia finito di aggiornare la pagina. Ho eseguito test con location.reload nel callback di ciascuno e al di fuori di ciascuno. Su 10 caselle selezionate, solo 7-8 vengono elaborati con la ricarica nel callback di $ .each e 3-4 se spostati dopo $ .each (sempre all'interno di .click). Ho bisogno di aspettare, in qualche modo, per $ .each per finire e poi aggiornare la pagina. C'è un modo per farlo?

$('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(); 
     }); 

risposta

6

Un modo semplice è quello di memorizzare il numero di elementi in un ambito globale e sottrarli. Quando l'ultimo elemento termina la richiesta, verrà ricaricata. Si noti che se alcune richieste restituiscono un errore, ciò non riuscirà, sarà necessario gestire l'evento di errore e sottrarre lo window.Remaining. Due o più clic potrebbero anche danneggiare questo metodo.

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

Bella idea di usare la proprietà 'length'. Probabilmente potresti evitare di eseguire il selettore due volte facendo qualcosa come 'window.Remaining = $ ('input: checked'). Each (function() {...}). Length'. : o) – user113716

+0

solo una nota a margine: perché lo stai mettendo sotto 'finestra'? Ciò funzionerebbe altrettanto bene nell'ambito locale. non c'è bisogno di inquinare lo spazio dei nomi globale. –

5

Non sono sicuro se questa è la soluzione migliore, ma un'idea sarebbe quella di incrementare un conteggio delle richieste inviate per ciascuno di essi, poi farlo diminuire come tornano le richieste.

Utilizzare il conteggio come contrassegno per determinare se l'reload() deve essere attivato.

Qualcosa di simile a questo:

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

probabilmente si dovrebbe avere un po 'di codice per evitare che il click si verifichi da un secondo clic. Probabilmente potresti usare la stessa variabile count per quello.

come in:

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

o una migliore idea potrebbe essere quella di utilizzare this solution from nsw1475 e inviare una sola richiesta per tutti le caselle se tale opzione è a vostra disposizione.

2

Un modo migliore, più efficiente e privo di bug per fare questo potrebbe essere quello di utilizzare la funzione each() per generare un array json memorizzando quali checkbox sono stati controllati, e quindi utilizzare .post per passare tutti i dati insieme . Al termine, l'aggiornamento della pagina di chiamata.