1

有没有人有关于如何从 $.Deferred() 获取上传进度的示例?我想像您使用 XHR.onprogress 一样收听进度事件

上下文:使用backbone.js 我想做这样的事情。保存模型后,我正在上传一个中等大小的 base64 编码图像。

var def = model.save();
def.progress(function(value){
    console.log(value);
});
4

2 回答 2

2

这很棘手,我不确定我的代码是否有效,只是给你一个基本的想法。您必须修改 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();
于 2013-05-04T06:33:35.230 回答
-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 是否已完成以执行其他操作。似乎目前正在满足我的需求。

于 2013-05-04T15:26:48.223 回答