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
File upload with Backbone
提问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.js和jquery.iframe-transport.js。
Setting data-remote="true"
with rails.jsallows me to bind to ajax:success
and 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:error
to handle error cases.
您显然应该绑定ajax:error
以处理错误情况。
For me, the data is sanitized in the ActiveRecord
model, so don't have to worry too much about the eval
statement.
对我来说,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 enctype
being set, and when it doesn't.
这将处理表单是否通过enctype
设置上传文件以及何时不上传的情况。
You could choose to call sanitize
on 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.sync
will merge any options via model.save(null, { /* options here */ })
with the $.ajax
instructions.
同样重要的是要注意的是,外的开箱,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:
所以这里是文件上传部分:
Once you get back the list_item object, you would just create a new field in your model and store list_item.filename
and asset_path(list_item)
.
取回 list_item 对象后,您只需在模型中创建一个新字段并存储list_item.filename
和asset_path(list_item)
。
Hope that helps.
希望有帮助。