web-dev-qa-db-ja.com

バックボーンを使用したファイルのアップロード

RailsアプリでBackbone.jsを使用しており、Backboneモデルの一部としてファイルのアップロードを行う必要があります。

Backboneが箱から出してマルチパートファイルのアップロードを可能にするとは思わない。誰かがプラグインまたは別の外部ライブラリを介してそれを機能させることができましたか?これをサポートするためにBackbone.jsを拡張するにはどうすればよいですか?

30

さまざまな方法を使用して数か月の試行の後、私自身の質問に答えます。私の解決策は次のとおりです(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)});"
20

jquery.iframe.transport プラグインを確認することをお勧めします。 Rails 3を使用している場合は、代わりに remotipart を使用できます(iframe.transportプラグインがバンドルされています)。これは、Railsのujsドライバーにフックして、のサポートを自動的に追加します。 ajaxリクエストでのファイルのアップロード。

3
Matt Burke

これを復活させます。

前の回答で述べたように、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 
});
_
1
jtrumbull

バックボーンがどのように機能するかを誤解していると思います。バックボーンは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.filename_とasset_path(list_item)を格納します。

お役に立てば幸いです。

0
Swift

下位互換性を壊してもかまわない場合は、 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=...
});
0