有没有人有关于如何从 $.Deferred() 获取上传进度的示例?我想像您使用 XHR.onprogress 一样收听进度事件
上下文:使用backbone.js 我想做这样的事情。保存模型后,我正在上传一个中等大小的 base64 编码图像。
var def = model.save();
def.progress(function(value){
console.log(value);
});
有没有人有关于如何从 $.Deferred() 获取上传进度的示例?我想像您使用 XHR.onprogress 一样收听进度事件
上下文:使用backbone.js 我想做这样的事情。保存模型后,我正在上传一个中等大小的 base64 编码图像。
var def = model.save();
def.progress(function(value){
console.log(value);
});
这很棘手,我不确定我的代码是否有效,只是给你一个基本的想法。您必须修改 ajax 选项model.save
或对所有 $.ajax 调用全局执行此操作。
这也不会进入延迟,您必须使用进度回调。从修补 ajax 选项的链接中包含 js 后,您将能够使用进度回调:
model.save({}, {
progress: function(e) {
//make sure we can compute the length
if(e.lengthComputable) {
//calculate the percentage loaded
var pct = (e.loaded / e.total) * 100;
//log percentage loaded
console.log(pct);
}
//this usually happens when Content-Length isn't set
else {
console.warn('Content Length not reported!');
}
}
})
另一种选择是修补Model.sync
:
ProgressModel = Backbone.Model.extend({
sync: function(method, model, options) {
function progress(e) {
model.trigger('progress', e)
}
var newOptions = _.defaults({
xhr: function() {
var xhr = $.ajaxSettings.xhr();
if(xhr instanceof window.XMLHttpRequest) {
xhr.addEventListener('progress', progress, false);
}
if(xhr.upload) {
xhr.upload.addEventListener('progress', progress, false);
}
return xhr;
}
}, options);
return Backbone.sync.call(this, method, model, newOptions);
}
});
// so now you can listen to progress event on model
model.on('progress', function(e) { })
model.save();
我决定只在模型上创建一个单独的方法,因为我只需要监视 POST 请求的进度。在我的收藏中,作为“添加”处理程序,我做了:
onAdd: function (model) {
var xhr = new XMLHttpRequest();
var $def = $.Deferred();
this.uploadQueue.push($def.promise());
xhr.open('POST', 'http://myapi/upload-image', true);
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
console.log((e.loaded / e.total) * 100);
}
}
xhr.onload = function(e) {
if (this.status == 201) {
console.log(this.responseText);
$def.resolve();
}
};
xhr.send(JSON.stringify(model.toJSON()));
}
然后稍后在我的代码中,我可以检查 collection.uploadQueue 是否已完成以执行其他操作。似乎目前正在满足我的需求。