2010-03-19 50 views
23

Quiero mostrar el progreso con la barra de progreso de jquery ui cuando se produce un pedido de Ajax y cuando finaliza. El problema es que no sé cómo establecer valores para la barra de progreso en función del progreso de la solicitud de Ajax. Aquí hay un código para comenzar:que muestra el progreso de la barra de progreso con la solicitud ajax

function ajaxnews() 
    { 
     $('.newstabs a').click(function(e){ 
      var section = $(this).attr('id'); 
      var url = base + 'news/section/' + section; 

      $.ajax({ 
       url : url, 
       dataTye : 'html', 
       start : loadNews, 
       success : fillNews 
      }); 
     }); 
    } 



// start callback functions 
    function loadNews() 
    { 

     $('#progressbar').fadeIn(); 
     $('#progressbar').progressbar({ //how shoud I set the values here}); 
    } 

    function fillNews() 
    { 
    $('#progressbar').progressbar('option', 'value', ?? /* how do I find this?*/); 
    $('#progressbar').fadeOut(); 
    } 
+1

Puede obtener el estado de descarga uniéndose al evento progress. Verifique este ejemplo - https://gist.github.com/nebirhos/3892018 – Tushar

+1

También - https://github.com/kpozin/jquery-ajaxprogress – Tushar

+0

Aquí implemento proggressbar (http: // js-control-files-uploader .itweb-projects.com /), pero uso xhr.upload.addEventListener ('progress', ... Github: https://github.com/dimitardanailov/js-control-files-uploader/blob/master /javascript/js-control-files-uploader/fileapi.js –

Respuesta

27

El problema fundamental es que no sabe cuánto tiempo llevará la solicitud.

Para la barra de progreso, debe establecer un porcentaje o una cantidad de pasos completados.

Si no desea que la barra de progreso simplemente salte de 0 a 100, debe tener alguna manera de medir la tasa de finalización antes de que finalice la solicitud.

Si puede adivinar cuánto tiempo lleva, puede usar un temporizador para que incremente gradualmente a, por ejemplo, 90%, automáticamente, y cuando llegue la respuesta del servidor, configúrelo en 100%. Por supuesto, eso es fingir un poco.

Si tiene más de una solicitud, puede usar el número de solicitudes completadas como un porcentaje. Si tiene sentido, puede desglosar su solicitud individual en múltiples, pero piense cuidadosamente sobre el impacto que esto tiene en el tráfico de la red y los tiempos de respuesta. No solo lo hagas por el bien de la barra de progreso.

Si la solicitud realmente lleva mucho tiempo, puede disparar solicitudes adicionales al servidor para consultar el progreso. Pero eso podría significar mucho trabajo en el lado del servidor.

, pero las barras de progreso sentimos son difíciles ...

+10

... podría seguir con los gifs de preloader clásicos, ¿eh? – yretuta

+2

sí ;-) ....... – Thilo

1

Editar: Para la posteridad He dejado mi respuesta anterior a continuación, pero viendo que en realidad no responder a la pregunta que se hace que estoy proporcionando una nueva respuesta.

Algunos de los comentarios sobre la pregunta han señalado nuevos métodos para lograr esto. Gracias a HTML5 y al XHR2 más nuevo, es posible realizar devoluciones de llamadas sobre el progreso de las solicitudes de AJAX. Esto implica que agrega detectores de eventos al objeto XHR y proporciona devoluciones de llamadas a las propiedades apropiadas. La página This tiene buenos ejemplos para subir y descargar y this git repo se ve bien y se ha actualizado recientemente.

Además, si está realmente interesado en profundizar en el XHR y sobrescribe, la publicación this Mozilla doc también debería ayudar mucho. Y, de hecho, este doc post parece ser lo que el git repo que mencioné se basó en.

Respuesta anterior: Este es un viejo problema para las personas que escriben aplicaciones web y, aunque Thilo tenía razón, esto ya no es tan difícil como lo era antes. La mejor solución (actual) es "dividir" los archivos que está cargando y actualizar su barra de progreso cada vez que sube un fragmento. This SO question y su respuesta es un buen lugar para comenzar a entender este concepto e incluso cómo aplicarlo a su situación.

Pero basta con decir que lo que hará es tomar el archivo que está cargando y dividirlo en partes más pequeñas en el lado del cliente. Hay varios beneficios potenciales para esto, pero el principal en este caso es que le permite saber cada vez que un porcentaje específico del archivo ha sido cargado en el servidor. Y, obviamente, cada vez que se sube un trozo puede actualizar la barra de progreso en consecuencia.

La fragmentación del archivo de esta manera también le permite "pausar" o "reanudar" de manera efectiva las cargas, ya que puede cargar diferentes partes de un archivo en cualquier momento.

+0

¿Qué se está subiendo? – 1983

+0

No estoy seguro de entender su pregunta. Un usuario carga un archivo que es capturado por su código front-end. A continuación, divide el archivo en fragmentos y lo envía a su código del lado del servidor un fragmento a la vez. Puede usar esto en cualquier tipo de archivo y le permite saber qué porcentaje de un archivo se ha subido en un momento dado. –

+1

No se menciona la carga de archivos en el PO. – 1983

2

Enfrenté esta situación en la aplicación interna de nuestra empresa. Era una aplicación crítica y necesitábamos mostrar el progreso al usuario. Por lo tanto, a pesar de que @Thilo mencionó el tráfico de red, tuvimos que implementarlo para que el usuario pudiera estar informado cuando el proceso de larga ejecución finalizara y su progreso en el tiempo.

Lo descompusimos en pedazos pequeños.

  1. Engendrar un hilo en el código del lado del servidor para ejecutar el proceso en particular. Para ASP.Net era así:

    System.Threading.ThreadPool.QueueUserWorkItem(AddressOf MyProcessRoutine, objectParameter)

  2. Dentro de este "MyProcessRoutine" ejecutar el código de larga duración y actualizar una variable estática para el contador o persistir en la base de datos, para cada paso que desee monitor.

  3. Crea otra rutina de funciones que sigue revisando este contador y devuelve el valor actual. Por ejemplo: Public Shared Function CheckStatus() As Integer

  4. Utilizando su código de cliente mantener el sondeo esta rutina decir cada 5 segundos (dependiendo de la cantidad de tráfico de red que puede pagar y la cantidad de precisión desea Por ejemplo:. timer = setInterval("MyWebService.CheckStatus();", 500);

  5. en su código de cliente, utilice este valor devuelto (contador) para actualizar la barra de progreso.

además apenas de un contador, también puede devolver un objeto que contiene datos relevantes como registro-id para mostrar al usuario acerca donde el proceso es curre ntly at.

Asegúrese de manejar el hilo con mucho cuidado, manejar todas las excepciones posibles y realizar una limpieza adecuada.

2

no uso jquery, pero esto quizás pueda ayudarlo.

Es una barra de progreso Ajax animada con respaldo falso.

i sólo tiene que pasar un tamaño falsa sabiendo el tamaño medio de mis guiones

así que si mis guiones son alrededor 50-100kb i ajustar el tamaño de falso a 150 kb.

si la longitud calculada no está disponible, uso el tamaño falso.

en este script, agregué también una comprobación adicional de que el tamaño de la barra siempre es más pequeño que el contenedor.

simplemente multiplicando el tamaño falso * 2 .. si es más pequeño que los datos cargados.

para hacer que las cosas luzcan bonitas, agregué también un efecto de transición css3 para que retrase 700ms.

este retraso de animación agrega todo lo que necesita para que la barra de progreso parezca real.

copie & pegue en un archivo html y consulte con un navegador moderno como chrome.

reemplazar YOURSITE con un sitio de contenido ajax ... o lo que sea.

<!doctype html> 
<html> 
<head> 
<meta charset="utf-8"> 
<title>Ajax Progress</title> 
<style> 
#progress{ 
width:300px; 
height:20px; 
border:1px solid rgba(0,0,0,0.5); 
} 
#bar{ 
width:0%; 
height:20px; 
background-color:green; 
-webkit-transition:width 700ms ease; 
} 
</style> 
<script> 
var 
pb, 
fakeSize=100000,//~100kb 
progress=function(e){ 
fakeSize=(e.loaded>fakeSize?(fakeSize*2):fakeSize);//Bonus 
var tot=(e.lengthComputable?e.total:fakeSize); 
pb.style.width=(100/tot*e.loaded)+'%'; 
}, 
onloaded=function(e){ 
pb.style.width='100%'; 
}, 
ajax=function(a,c){ 
c=new XMLHttpRequest; 
c.open('GET',a); 
c.onprogress=progress; 
c.onload=onloaded; 
c.send() 
}; 
window.onload=function(){ 
pb=document.getElementById('bar'); 
ajax('YOURSITE'); 
} 
</script> 
</head> 
<body> 
<div id="progress"><div id="bar"></div></div> 
</body> 
</html> 

que, básicamente, sólo tiene que utilizar la función de progreso en jQuery y luego poner el listón a 100% cuando la escritura se ha cargado.

Cuestiones relacionadas