Ich habe drei verschiedene Möglichkeiten ausprobiert, um die Konstruktion des Ajax-Objekts abzufangen:
- Mein erster Versuch verwendet
xhrFields
, aber das erlaubt nur einen Listener, hängt nur an den Download-Fortschritt (nicht an den Upload) und erfordert scheinbar unnötiges Kopieren und Einfügen.
- Mein zweiter Versuch fügte
progress
dem zurückgegebenen Versprechen eine Funktion hinzu, aber ich musste meine eigene Reihe von Handlern warten. Ich konnte kein gutes Objekt zum Anhängen der Handler finden, da ich an einem Ort auf das XHR und an einem anderen auf das jQuery XHR zugreifen würde, aber ich hatte nie Zugriff auf das zurückgestellte Objekt (nur dessen Versprechen).
- Bei meinem dritten Versuch hatte ich direkten Zugriff auf das XHR zum Anhängen von Handlern, musste aber erneut viel Code kopieren und einfügen.
- Ich habe meinen dritten Versuch abgeschlossen und jQuery's
ajax
durch meinen eigenen ersetzt. Das einzige mögliche Manko ist, dass Sie Ihre eigene xhr()
Einstellung nicht mehr verwenden können . Sie können dies berücksichtigen, indem Sie überprüfen, ob options.xhr
es sich um eine Funktion handelt.
Ich rufe meine promise.progress
Funktion tatsächlich auf, xhrProgress
damit ich sie später leicht finden kann. Vielleicht möchten Sie es anders benennen, um Ihre Upload- und Download-Listener zu trennen. Ich hoffe, das hilft jemandem, auch wenn das Originalplakat bereits das bekommen hat, was er brauchte.
(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 );