有没有人有关于如何从$ .Deferred()获取上传进度的示例?我想听听像XHR.onprogress
那样的进展事件上下文: 使用backbone.js我想做这样的事情。保存模型时,我正在上传一个中等大小的base64编码图像。
var def = model.save();
def.progress(function(value){
console.log(value);
});
答案 0 :(得分:2)
这很棘手,我不确定我的代码是否有效,只是给你一个基本的想法。您必须修改model.save
或do it globally for all $.ajax calls中的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();
答案 1 :(得分:-1)
我决定在模型上创建一个单独的方法,因为我只需要监视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以执行其他操作。似乎现在正在满足我的需求。