【问题标题】:File upload with Backbone使用 Backbone 上传文件
【发布时间】:2011-06-28 00:18:27
【问题描述】:

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

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

【问题讨论】:

    标签: javascript ruby-on-rails backbone.js


    【解决方案1】:

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

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

    设置data-remote="true"rails.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
    });
    

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

    【讨论】:

    • 整洁。不过有两个问题。在您的控制器中,您是打算执行Post.new(params[:post]) 还是实际上是指Post.create(params[:post])?其次,您会将$('form').bind('ajax:success') 回调放在给定表单的Backbone.View 类中的什么位置?谢谢!
    • 很好,我的错字。应该是Post.create。我会将 $('form').bind('ajax:success') 放在呈现表单的 Backbone 视图中。
    • 在表单中添加data-type="json",即可移除视图。
    • 正如@Maletor 指出的,您可以简单地返回 JSON。我在使用早期版本的 remotipart 时遇到了问题,但现在它似乎运行良好。
    【解决方案2】:

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

    【讨论】:

    • 谢谢马特。我最终完全使用了您刚才描述的内容,但没有及时更新这个问题。
    【解决方案3】:

    复活这个。

    如前面的回答中提到的,multipart/form-data 请求可以通过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 
    });
    

    【讨论】:

      【解决方案4】:

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

      话虽如此,将文件与模型关联起来需要做的是 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)

      希望对您有所帮助。

      【讨论】:

      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-22
        • 1970-01-01
        • 2014-08-15
        相关资源
        最近更新 更多