Jquery Deferred()上传进度

时间:2013-05-03 22:05:53

标签: backbone.js jquery-deferred jqxhr

有没有人有关于如何从$ .Deferred()获取上传进度的示例?我想听听像XHR.onprogress

那样的进展事件

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

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

2 个答案:

答案 0 :(得分:2)

这很棘手,我不确定我的代码是否有效,只是给你一个基本的想法。您必须修改model.savedo 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以执行其他操作。似乎现在正在满足我的需求。