2010-10-13 14 views
5

Hola, tengo un gran problema que me ha molestado durante bastante tiempo, la mayoría de las veces he podido evitarlo pero ahora no hay otra manera. A continuación se muestra una función que cuando se ejecuta envía una solicitud posterior para cada recuadro marcado. Necesito que espere hasta que el $ .each haya terminado de actualizar la página. He realizado pruebas con location.reload en la devolución de llamada de cada uno y fuera de cada uno. De 10 casillas seleccionadas, solo se procesan 7-8 con la recarga en la devolución de llamada de $ .each y 3-4 si se mueve después de $ .each (aún dentro del clic.) Necesito que espere, de alguna manera, por $ .each para terminar y luego actualizar la página. ¿Hay una manera de hacer eso?

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

Respuesta

6

Una forma simple es almacenar el número de elementos en un ámbito global y restarlos. Cuando el último elemento termine la solicitud, se volverá a cargar. Tenga en cuenta que si alguna solicitud devuelve un error, esto fallará, debe manejar el evento de error y restar el window.Remaining. Dos o más clics también pueden dañar este método.

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

Una buena idea para usar la propiedad 'length'. Probablemente podría evitar ejecutar el selector dos veces haciendo algo como 'window.Remaining = $ ('input: checked'). Each (function() {...}). Length'. : o) – user113716

+0

solo una nota al margen: ¿por qué lo pones en 'ventana'? Esto funcionaría igual de bien en el ámbito local. no hay necesidad de contaminar el espacio de nombres global. –

5

No estoy seguro si esta es la mejor solución, pero una idea sería la de incrementar un recuento de las solicitudes enviadas para cada uno, y luego disminuirlo como regresan las solicitudes.

Usa el recuento como una bandera para determinar si el reload() debe disparar.

Algo como esto:

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

probablemente debería tener un poco de código para evitar la click que se produzcan a partir de un segundo clic. Probablemente puedas usar la misma variable count para eso.

como en:

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

o una mejor idea puede ser el uso de this solution from nsw1475 y enviar solamente una solicitud de todas las casillas si esa opción está disponible para usted.

2

Una manera mejor, más eficiente y sin errores de hacer esto podría ser usar la función cada() para generar una matriz json almacenando qué casillas de verificación se han verificado y luego usar .post para pasar todos sus datos juntos . Una vez hecho esto, llame a la actualización de la página.