使用骨干上传文件

File upload with Backbone

本文关键字:文件      更新时间:2023-09-26

我在Rails应用程序中使用Backbone.js,我需要将文件上传作为Backbone模型的一部分。

我不相信 Backbone 允许开箱即用的多部分文件上传。有没有人设法通过某个插件或另一个外部库让它工作?如何扩展 Backbone.js 以支持此功能?

经过几个月的试用,使用不同的方法回答我自己的问题。我的解决方案如下(使用Rails(。

对于任何需要文件上传的形式,我会设置data-remote="true"enctype="multipart/form-data",并包括rails.js和jquery.iframe-transport.js。

使用 rails 设置data-remote="true".js允许我绑定到ajax:success并在成功时创建 Backbone.js 模型。

.HTML:

<form action="/posts.js" method="post" data-remote="true" enctype="multipart/form-data">
  <input type="text" name="post[message]" />
  <input type="file" name="post[file]" />
  <button>Submit</button>
</form>

JavaScript:

显然,您应该绑定ajax:error来处理错误情况。

对我来说,数据在ActiveRecord模型中进行了清理,所以不必太担心eval语句。

$('form').bind('ajax:success', function(event, data) {
  new Model(eval(data)); // Your newly created Backbone.js model
});

导轨控制器:

class PostsController < ApplicationController
  respond_to :js
  def create
    @post = Post.create(params[:post])
    respond_with @post
  end
end

Rails View (create.js.haml(:

使用远程处理宝石。

这将处理表单在设置enctype的情况下进行文件上传的情况,以及未设置

文件的情况。

您可以选择在此处致电sanitize回复。

= remotipart_response do
  - if remotipart_submitted?
    = "eval(#{Yajl::Encoder.encode(@post)});"
  - else
    =raw "eval(#{Yajl::Encoder.encode(@post)});"

你可能想看看jquery.iframe.transport插件。如果你使用的是rails 3,你可以使用remotipart(它捆绑了iframe.transport插件(,它钩接到rails的ujs驱动程序,以自动添加对ajax请求中文件上传的支持。

复活这个。

如前面的回答所述,多部分/表单数据请求可以通过jQuery.ajax执行:

var formData = new FormData();
var input = document.getElementById('file');
formData.append('file', input.files[0]);
$.ajax({
  url: 'path/to/upload/endpoint'
  type:'POST',
  data: formData,
  processData: false,
  contentType: false
});

同样重要的是要注意,开箱即用的Backbone.sync将通过model.save(null, { /* options here */ })$.ajax说明合并任何选项。

您的保存过程将如下所示:

var model = new Model({
  key: 'value'
});
var input = document.getElementById('file');
var formData = new FormData();
_.each(model.keys(), function (key) { // Append your attributes
  formData.append(key, model.get(key));
});
formData.append('file', input.files[0]); // Append your file
model.save(null, {
  data: formData, 
  processData: false,
  contentType: false 
});

我认为你误解了骨干网的工作原理。Backbone是一个用于javascript的MVC库,而不是一个Web服务器。 文件上传在客户端浏览器和服务器之间协商。主干只是中间层,可帮助您以简单、方便的方式组织和呈现数据。

话虽如此,要将文件与模型关联,您需要做的是 1( 使用 rails 处理上传,然后 2( 将文件名和位置存储在模型中的字符串中。

所以这是文件上传部分:

http://khamsouk.souvanlasy.com/articles/ajax-file-uploads-in-rails-using-attachment_fu-and-responds_to_parent

取回list_item对象后,只需在模型中创建一个新字段并存储list_item.filenameasset_path(list_item)

希望有帮助。

如果您不介意破坏向后兼容性,则可以利用 XHR2 和 FormData

就这么简单:

var data = new FormData( $('form.someForm').get(0) );
$.ajax('http://*****.com', {
  type:'POST',
  data: data,
  processData: false,
  contentType: false // it automaticly sets multipart/form-data; boundary=...
});