我在Rails应用程序中使用Backbone.js,我需要将文件上传作为其中一个Backbone模型的一部分。
我不相信Backbone允许开箱即用的多部分文件上传。有没有人设法通过一些插件或其他外部lib工作?我如何扩展Backbone.js来支持这个?
答案 0 :(得分:20)
使用不同方法试用几个月后回答我自己的问题。我的解决方案如下(使用Rails)。
对于需要上传文件的任何表单,我会设置data-remote="true"
和enctype="multipart/form-data"
并添加rails.js和jquery.iframe-transport.js。
使用rails.js设置data-remote="true"
可以让我绑定到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
});
Rails控制器:
class PostsController < ApplicationController
respond_to :js
def create
@post = Post.create(params[:post])
respond_with @post
end
end
Rails查看(create.js.haml):
使用remotipart gem。
这将处理表单执行文件上传时设置enctype
的情况,以及未设置的情况。
您可以选择在此处为您的回复致电sanitize
。
= remotipart_response do
- if remotipart_submitted?
= "eval(#{Yajl::Encoder.encode(@post)});"
- else
=raw "eval(#{Yajl::Encoder.encode(@post)});"
答案 1 :(得分:3)
您可能需要查看jquery.iframe.transport插件。如果您正在使用rails 3,则可以使用remotipart代替它(它捆绑iframe.transport插件),该插件挂钩到rails的ujs驱动程序,以自动添加对ajax请求中文件上载的支持。
答案 2 :(得分:1)
恢复这一个。
如前面的答案中所述,可以通过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
});
答案 3 :(得分:0)
我认为你误解了骨干的运作方式。 Backbone是javascript的MVC库,而不是Web服务器。文件上载在客户端浏览器和服务器之间协商。 Backbone只是中间层,可以帮助您轻松,方便地组织和呈现数据。
话虽这么说,将文件与模型关联起来需要做的是1)使用rails处理上传,然后2)将文件名和位置存储在模型中的字符串中。
所以这是文件上传部分:
返回list_item对象后,您只需在模型中创建一个新字段,然后存储list_item.filename
和asset_path(list_item)
。
希望有所帮助。
答案 4 :(得分:0)
如果您不介意破坏向后兼容性,则可以利用XHR2 and 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=...
});