Probé tres formas diferentes de interceptar la construcción del objeto Ajax:
- Se usó mi primer intento
xhrFields
, pero eso solo permite un oyente, solo se adjunta al progreso de la descarga (no de la carga) y requiere lo que parece ser copiar y pegar innecesario.
- Mi segundo intento adjuntó una
progress
función a la promesa devuelta, pero tuve que mantener mi propia matriz de controladores. No pude encontrar un buen objeto para adjuntar los controladores porque en un lugar accedería al XHR y en otro tendría acceso al jQuery XHR, pero nunca tuve acceso al objeto diferido (solo su promesa).
- Mi tercer intento me dio acceso directo al XHR para adjuntar controladores, pero nuevamente requirió mucho código para copiar y pegar.
- Terminé mi tercer intento y reemplacé el de jQuery
ajax
con el mío. El único defecto potencial es que ya no puede utilizar su propio xhr()
entorno. Puede permitirlo comprobando si options.xhr
es una función.
De hecho, llamo a mi promise.progress
función xhrProgress
para poder encontrarla fácilmente más tarde. Es posible que desee nombrarlo de otra manera para separar sus oyentes de carga y descarga. Espero que esto ayude a alguien incluso si el póster original ya tiene lo que necesitaba.
(function extend_jQuery_ajax_with_progress( window, jQuery, undefined )
{
var $originalAjax = jQuery.ajax;
jQuery.ajax = function( url, options )
{
if( typeof( url ) === 'object' )
{options = url;url = undefined;}
options = options || {};
// Instantiate our own.
var xmlHttpReq = $.ajaxSettings.xhr();
// Make it use our own.
options.xhr = function()
{return( xmlHttpReq );};
var $newDeferred = $.Deferred();
var $oldPromise = $originalAjax( url, options )
.done( function done_wrapper( response, text_status, jqXHR )
{return( $newDeferred.resolveWith( this, arguments ));})
.fail( function fail_wrapper( jqXHR, text_status, error )
{return( $newDeferred.rejectWith( this, arguments ));})
.progress( function progress_wrapper()
{
window.console.warn( "Whoa, jQuery started actually using deferred progress to report Ajax progress!" );
return( $newDeferred.notifyWith( this, arguments ));
});
var $newPromise = $newDeferred.promise();
// Extend our own.
$newPromise.progress = function( handler )
{
xmlHttpReq.addEventListener( 'progress', function download_progress( evt )
{
//window.console.debug( "download_progress", evt );
handler.apply( this, [evt]);
}, false );
xmlHttpReq.upload.addEventListener( 'progress', function upload_progress( evt )
{
//window.console.debug( "upload_progress", evt );
handler.apply( this, [evt]);
}, false );
return( this );
};
return( $newPromise );
};
})( window, jQuery );