Uploading files to tastypie with Backbone?

烂漫一生 提交于 2019-12-03 08:59:11

You may override sync method to serialize with FormData api to be able to submit files as model's attributes.

Please note that it will work only in modern browsers. It worked with Backbone 0.9.2, I advise to check the default Backbone.sync and adopt the idea accordingly.

function getValue (object, prop, args) {
  if (!(object && object[prop])) return null;
  return _.isFunction(object[prop]) ?
    object[prop].apply(object, args) :
    object[prop];
}

var MultipartModel = Backbone.Model.extend({
  sync: function (method, model, options) {
    var data
      , methodMap = {
          'create': 'POST',
          'update': 'PUT',
          'delete': 'DELETE',
          'read':   'GET'
        }
      , params = {
          type: methodMap[method],
          dataType: 'json',
          url: getValue(model, 'url') || this.urlError()
        };

    if (method == 'create' || method == 'update') {
      if (!!window.FormData) {
        data = new FormData();
        $.each(model.toJSON(), function (name, value) {
          if ($.isArray(value)) {
            if (value.length > 0) {
              $.each(value, function(index, item_value) {
                data.append(name, item_value);
              })
            }
          } else {
            data.append(name, value)
          }
        });
        params.contentType = false;
        params.processData = false;
      } else {
        data = model.toJSON();
        params.contentType = "application/x-www-form-urlencoded";
        params.processData = true;
      }
      params.data = data;
    }

    return $.ajax(_.extend(params, options));
  },

  urlError: function() {
    throw new Error('A "url" property or function must be specified');
  }

});

This is excerpt from upload view, I use <input type="file" name="file" multiple> for file uploads so user can select many files. I then listen to the change event and use collection.create to upload each file.

var MultipartCollection = Backbone.Collection.extend({model: MultipartModel});


var UploadView = Backbone.View.extend({

  events: {
    "change input[name=file]": "changeEvent"
  },

  changeEvent: function (e) {
    this.uploadFiles(e.target.files);
    // Empty file input value:
    e.target.outerHTML = e.target.outerHTML;
  },

  uploadFiles: function (files) {
    _.each(files, this.uploadFile, this);
    return this;
  },

  uploadFile: function (file) {
    this.collection.create({file: file});
    return this;
  }

})
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!