ฉันลองใช้วิธีสกัดกั้นการสร้างวัตถุ 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 );