Я спробував про три різні способи перехоплення конструкції об'єкта Ajax:
- Моя перша спроба, що використовується
xhrFields
, але це дозволяє лише одному слухачеві, додає лише для завантаження (не завантаження) прогрес і вимагає того, що здається непотрібним копіювати та вставляти.
- Моя друга спроба додала:
progress
функцію до повернутої обіцянки, але мені довелося підтримувати власний масив обробників. Я не зміг знайти хороший об’єкт, щоб приєднати обробники, тому що одне місце я отримав би доступ до XHR, а інше я отримав би доступ до jQuery XHR, але я ніколи не мав доступу до відкладеного об'єкта (лише його обіцянка).
- Моя третя спроба дала мені прямий доступ до XHR для приєднання обробників, але знову вимагало багато копіювати та вставляти код.
- Я завершив свою третю спробу і замінив jQuery на
ajax
свою. Єдиний потенційний недолік - ви більше не можете використовувати власні xhr()
налаштування. Ви можете дозволити це, перевіривши, чи options.xhr
є функцією.
Я фактично називаю свою promise.progress
функцію, xhrProgress
щоб потім її легко було знайти. Ви можете назвати щось інше, щоб розділити слухачів, які завантажують і завантажують. Я сподіваюся, що це допоможе комусь, навіть якщо оригінальний афіша вже отримав те, що йому потрібно.
(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 );