Backbone.js和FormData

Leo*_*das 14 javascript html5 json form-data backbone.js

有没有办法使用Backbone.js和它的模型架构,我可以将formdata对象发送到服务器?我遇到的问题是Backbone发送的所有内容都被编码为JSON,因此formdata对象未正确发送(显然).

我正在通过制作一个直接的jQuery ajax请求并将formdata对象作为数据属性来暂时解决这个问题,但这不太理想.

Koe*_*en. 18

这是一个覆盖sync方法的解决方案,我用它来允许文件上传.

在这种情况下,我重写模型的sync方法,但这也可以是Backbone.sync方法.

var FileModel = Backbone.Model.extend({

  urlRoot: CMS_ADMIN_URL + '/config/files',

  sync: function(method, model, options){

    // Post data as FormData object on create to allow file upload
    if(method == 'create'){
      var formData = new FormData();

      // Loop over model attributes and append to formData
      _.each(model.attributes, function(value, key){
        formData.append(key, value);
      });

      // Set processData and contentType to false so data is sent as FormData
      _.defaults(options || (options = {}), {
        data: formData,
        processData: false,
        contentType: false
      });
    }
    return Backbone.sync.call(this, method, model, options);
  }
});
Run Code Online (Sandbox Code Playgroud)

编辑:

要跟踪上传进度,您可以为xhr选项添加选项:

...

_.defaults(options || (options = {}), {
  data: formData,
  processData: false,
  contentType: false
  xhr: function(){
    // get the native XmlHttpRequest object
    var xhr = $.ajaxSettings.xhr();
    // set the onprogress event handler
    xhr.upload.onprogress = function(event) {
      if (event.lengthComputable) {
        console.log('%d%', (event.loaded / event.total) * 100);
        // Trigger progress event on model for view updates
        model.trigger('progress', (event.loaded / event.total) * 100);
      }
    };
    // set the onload event handler
    xhr.upload.onload = function(){
      console.log('complete');
      model.trigger('progress', 100);
    };
    // return the customized object
    return xhr;
  }
});

...
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的答案,IMO在这个页面上是最好的.处理服务器通信的正确方法是编辑同步方法,这里在模型级别,但它*不*需要广泛地修补它:只需编辑选项哈希(保存数据和xhr选项),你就完成了. (2认同)

Pri*_*ner 7

只是为这个问题添加一个答案,以下是我如何去做而不必覆盖sync:

在我看来,我有一些像:

$('#' + $(e.currentTarget).data('fileTarget')).trigger('click').unbind('change').bind('change', function(){
    var form_data = new FormData();
    form_data.append('file', $(this)[0].files[0]);
    appManager.trigger('user:picture:change', form_data);
});
Run Code Online (Sandbox Code Playgroud)

然后,它会在执行此操作的控制器中触发一个函数:

var picture_entity = new appManager.Entities.ProfilePicture();
picture_entity.save(null, {
    data: data,
    contentType: false,
    processData: false,
});
Run Code Online (Sandbox Code Playgroud)

那时,我data用我的FormData对象覆盖了jQuery .


Roy*_*M J 7

我有类似的要求,这就是我做的:

在视图中:

var HomeView = Backbone.View.extend({
    el: "#template_loader",
    initialize: function () {
        console.log('Home View Initialized');
    },
    render: function () {
        var inputData = {
            cId: cId,
            latitude: latitude,
            longitude: longitude
        };

        var data = new FormData();

        data.append('data', JSON.stringify(inputData));

        that.model.save(data, {
            data: data,
            processData: false,
            cache: false,
            contentType: false,
            success: function (model, result) {
                alert("Success");
            },
            error: function () {
                alert("Error");
            }
        });
    }
});    
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.