RailsアプリでBackbone.jsを使用しており、Backboneモデルの一部としてファイルのアップロードを行う必要があります。
Backboneが箱から出してマルチパートファイルのアップロードを可能にするとは思わない。誰かがプラグインまたは別の外部ライブラリを介してそれを機能させることができましたか?これをサポートするためにBackbone.jsを拡張するにはどうすればよいですか?
さまざまな方法を使用して数か月の試行の後、私自身の質問に答えます。私の解決策は次のとおりです(Railsを使用)。
ファイルのアップロードが必要なフォームの場合は、data-remote="true"
とenctype="multipart/form-data"
を設定し、 Rails.js と jquery.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)});"
jquery.iframe.transport プラグインを確認することをお勧めします。 Rails 3を使用している場合は、代わりに remotipart を使用できます(iframe.transportプラグインがバンドルされています)。これは、Railsのujsドライバーにフックして、のサポートを自動的に追加します。 ajaxリクエストでのファイルのアップロード。
これを復活させます。
前の回答で述べたように、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
});
_
バックボーンがどのように機能するかを誤解していると思います。バックボーンはJavaScript用のMVCライブラリであり、Webサーバーではありません。ファイルのアップロードは、クライアントのブラウザとサーバーの間でネゴシエートされます。バックボーンは、データを簡単で便利な方法で整理および表示するのに役立つ中間層にすぎません。
そうは言っても、ファイルをモデルに関連付けるために必要なことは、1)アップロードをRails)で処理し、2)ファイル名と場所をモデル内の文字列に格納することです。
したがって、ファイルのアップロード部分は次のとおりです。
List_itemオブジェクトを取得したら、モデルに新しいフィールドを作成し、_list_item.filename
_とasset_path(list_item)
を格納します。
お役に立てば幸いです。
下位互換性を壊してもかまわない場合は、 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=...
});