web-dev-qa-db-ja.com

Rails:CoffeeScriptまたはJavaScriptアセットファイルのコントローラーインスタンス変数にアクセスする

Rails 3.1では、<%= @foo%>などの構文を使用して、アセットjs.erbまたはcoffee.erbファイル内のコントローラーインスタンス変数にアクセスすることはできません。それでは、コントローラー変数をCoffeeScriptまたはJavaScriptアセットに渡すための最良の方法は何かということです。

この質問はフォーラムで複数の複雑な形式で尋ねられていますが、もう一度質問する私のポイントは、すべての推奨事項がまとめられ、提供されたコードがシンプルで読みやすい場所を持つことです。また、応答ファイルを表示するのではなく、特にアセットを参照していることに注意してください。

40
Safa Alai

過去にこれを行ったいくつかの方法

データを非表示フィールドに入れ、js/coffeeのデータにアクセスします

# single value
<%= hidden_field_tag "foo_name", @foo.name, { :id => "foo-name" } %>
$('#foo-name').val();

# when the 'value' has multiple attributes
<%= hidden_field_tag "foo", @foo.id, { :id => "foo", "data-first-name" => @foo.first_name, "data-last-name" => @foo.last_name } %>
$foo = $('#foo')
console.log $foo.val()
console.log $foo.data("firstName")
console.log $foo.data("lastName")

別のオプション:データをerbのjsデータ構造にロードし、js/coffeeからアクセスします

<% content_for(:head) do %>
    <script>
    window.App = window.App || {};
    window.App.Data = window.App.Data || {};
    window.App.Data.fooList = [
        <% @list.each do |foo| %>
            <%= foo.to_json %>,
        <% end %>
    ];
    </script>
<% end %>


# coffee
for foo in window.App.Data.fooList
    console.log "#{foo.id}, #{foo.first_name} #{foo.last_name}"

私はRubyからこのようなerbでjavascriptデータを構築することの大ファンではありません。それについて何かが間違っているように感じます。

および別のオプション:ajax呼び出しを行い、サーバーからデータをオンデマンドで取得します

他のアイデアやアプローチにも興味があります

27
house9

この特定のトピックについて、本当にすてきなレールキャストと非常に最近(2012年2月)があります。 #324 JavaScriptにデータを渡す

スクリプトタグ、データ属性、Gon gemの3つの方法を示しています。家は利用可能なすべてのテクニックをカバーしたと思います。 AJAX呼び出しを使用することは、大量のデータ、動的データ、または両方の組み合わせがある場合に最適です。

9
Max

非表示フィールドを使用するのではなく、jqueryが取得できるコンテナdivにデータ属性を追加することにしました。

<div class="searchResults" data-query="<%= @q %>"></div>

次にjqueryがそれにアクセスします

url: "/search/get_results?search[q]=" + $(".searchResults").data("query") + "&page=" + p

これがデータをjavascriptに渡す最もクリーンな方法だと思います。コントローラからRailsアセットパイプラインを使用してコーヒースクリプトファイルに変数を渡す方法を見つけられませんでした。これが現在使用している方法です。誰かがセットアップするまで待てないRailsが最適です。

5
Dave Robertson

コントローラー内:

@foo_attr = { "data-foo-1" => 1, "data-foo-2" => 2 }

ビュー(HAML)で:

#foo{@foo_attr}

CoffeeScriptアセットで:

$("#foo").data("foo-1")
$("#foo").data("foo-2")
3
michau

JavaScriptデータが手に負えない状況では、2015年であっても、gon gemを使用してRailsに移動することをお勧めします。gonを設定した後、データを単にRailsのgonオブジェクト。

(Gemfile)
gem 'gon'

(controller) 
def index 
  gon.products = Product.all 

(layouts) 
<%= include_gon %> 

(public/javascripts/your_js_can_be_here.js) 
alert(gon.products[0]['id'); 

(html source automatically produced) 
<script> 
  window.gon = {}; 
  gon.products = [{"created_at":"2015", "updated_at":"2015, "id":1, "etc":"etc"}];

Ron Bateのスクリーンキャストから、Gonまたは他の2つのRails-javascriptチャネルで、より詳細な実装の詳細を読むことができます。
http://railscasts.com/episodes/324-passing-data-to-javascript

1
Ninjaxor

コントローラーのparams配列に変数を編集して追加し、response.js.erbで変数にアクセスできます。 params[:value]の例を次に示します。

def vote
  value = params[:type] == "up" ? 1 : -1
  params[:value] = value
  @public_comment = PublicComment.find(params[:id])

  have_voted = @public_comment.evaluators_for(:pub_votes_up) << @public_comment.evaluators_for(:pub_votes_down)

  unless have_voted.include?(@current_user) # vote
    @public_comment.add_or_update_evaluation(:"pub_votes_#{params[:type]}", value, @current_user)
  else                                      # unvote
    @public_comment.delete_evaluation(:"pub_votes_#{params[:type]}", @current_user)
    params[:value] = 0
  end

  respond_to do |format|
    format.js # vote.js.erb
  end
end

次に、response.js.erbに付随する例を示します

button = $('<%= ".pub#{params[:type]}_#{params[:id]}" %>')
label = button.find('strong')
<% comment = PublicComment.find(params[:id]) %>
label.html('<%= comment.reputation_for(:"pub_votes_#{params[:type]}").to_i %>')

<% if params[:value] == 1 %>
  button.addClass('btn-success')
<% elsif params[:value] == -1 %>
  button.addClass('btn-danger')
<% else %>
  if button.hasClass('btn-success') { button.removeClass('btn-success') }
  if button.hasClass('btn-danger') { button.removeClass('btn-danger') }
<% end %>
0
Archonic