javascript 使用 Backbone 上传文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6500379/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 20:52:23  来源:igfitidea点击:

File upload with Backbone

javascriptruby-on-railsbackbone.js

提问by Jey Balachandran

I'm using Backbone.js in a Rails app and I need to do file uploads as part of one of the Backbone models.

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

I don't believe Backbone allows for multi-part file upload out of the box. Has anyone managed to get it working via some plugin or with another external lib? How can I extend Backbone.js to support this?

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

采纳答案by Jey Balachandran

Answering my own question after few months of trial using different methods. My solution is the following (with Rails).

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

For any form that requires file upload I would set data-remote="true"and enctype="multipart/form-data"and include rails.jsand jquery.iframe-transport.js.

对于任何形式的需要文件上传我会成立data-remote="true",并enctype="multipart/form-data"与包括rails.jsjquery.iframe-transport.js

Setting data-remote="true"with rails.jsallows me to bind to ajax:successand create the Backbone.js model on success.

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

HTML:

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:

JavaScript:

You should obviously bind ajax:errorto handle error cases.

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

For me, the data is sanitized in the ActiveRecordmodel, so don't have to worry too much about the evalstatement.

对我来说,ActiveRecord模型中的数据已经过清理,所以不必太担心eval语句。

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

Rails Controller:

导轨控制器:

class PostsController < ApplicationController
  respond_to :js

  def create
    @post = Post.create(params[:post])
    respond_with @post
  end
end

Rails View (create.js.haml):

Rails 视图(create.js.haml):

Using the remotipartgem.

使用remotipartgem。

This will handle the case when the form does file uploads with enctypebeing set, and when it doesn't.

这将处理表单是否通过enctype设置上传文件以及何时不上传的情况。

You could choose to call sanitizeon your response here.

您可以选择sanitize在此处要求您的回复。

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

回答by Matt Burke

You may want to check out the jquery.iframe.transportplugin. If you're using rails 3, you can use remotipartinstead (it bundles the iframe.transport plugin), which hooks into rails's ujs driver to automatically add support for file upload in ajax requests.

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

回答by jtrumbull

Resurrecting this one.

复活这个。

As mentioned in previous answers, a multipart/form-data request can be executed via jQuery.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
});

It is also important to note that, out-of-the-box, Backbone.syncwill merge any options via model.save(null, { /* options here */ })with the $.ajaxinstructions.

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

Your save procedure would look something like:

您的保存过程如下所示:

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 
});

回答by Cezary Daniel Nowak

If you don't mind to break backward compatibility, you can take advantage of XHR2 and FormData

It's simple as that:

如果你不介意破坏向后兼容性,你可以利用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=...
});

回答by Swift

I think you're misunderstanding how backbone works. Backbone is an MVC library for javascript, not a web server. File uploads are negotiated between the clients browser and your server. Backbone is just the middle layer that helps you organize and present data in an easy, convenient manner.

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

That being said, what you need to do to associate a file with your model is 1) handle the upload with rails and then 2) store the file name and location in a string within your model.

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

So here's the file uploading part:

所以这里是文件上传部分:

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

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

Once you get back the list_item object, you would just create a new field in your model and store list_item.filenameand asset_path(list_item).

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

Hope that helps.

希望有帮助。