35

在Rails 3.1中,無法使用諸如<%= @foo%>之類的語法訪問資產js.erb或coffee.erb文件中的控制器實例變量,其中@foo在控制器中設置。那麼問題是將控制器變量傳遞給CoffeeScript或JavaScript資源的最佳方式是什麼。Rails:CoffeeScript或JavaScript資源文件中的訪問控制器實例變量

這個問題在論壇上有多種複雜的形式,但我的要求是要有一個地方,所有的建議都彙集在一起​​,所提供的代碼簡單易讀。另外請注意,我特指資產而不是查看響應文件。

+0

這是http://stackoverflow.com/questions/8108511/how-to-access-instance-variables-in-coffeescript-engine-inside-a-slim-template的副本?看起來像接受的答案有幫助。 – Thilo 2011-12-15 01:20:59

+0

@Thilo據我所知,該問題是指views文件夾中的.slim模板,所以實際上,CoffeeScript將作爲視圖的一部分進行處理,而不是事先處理爲資產文件。如果我錯了,請糾正我。 – 2011-12-15 01:27:54

+0

是的,我對Rails不太瞭解,以確定這個答案是否適用。但要點似乎是將所有需要的實例變量渲染到一段Javascript中,以便其他資源可以引用。 – Thilo 2011-12-15 02:20:04

回答

26

幾個方法我已經在過去

做到了這一點把數據放到隱藏域,訪問在JS中的數據/咖啡

# 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") 

另一種選擇:將數據加載到JS中的數據結構ERB,由JS訪問它/咖啡

<% 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}" 

我不是這樣的ERB紅寶石構建的JavaScript數據的忠實粉絲,一些關於它只是感覺不對 - 它可以有效儘管

和另一種選擇:讓Ajax調用,並獲得按需從服務器的數據

我也有興趣在其他的想法和做法

8

有一個非常好的軌道演員和最近的事實(二月2012)關於這個特定的主題: #324 Passing Data to JavaScript

它顯示3種方式:腳本標記,數據屬性和GON寶石。 我覺得房子涵蓋了所有可用的技術。我只提到,當你有大量的數據,動態數據或兩者結合時,最好使用AJAX調用。

5

而不是使用隱藏字段我選擇將數據屬性添加到jquery可以拾取的容器div。

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

那麼jQuery來訪問它

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

我覺得這是將數據傳遞到JavaScript的最徹底的方法。發現無法通過控制器的rails資產管道將變量傳遞給咖啡腳本文件後。這是我現在使用的方法。不能等到有人用最好的導軌設置控制器方式。

3

在控制器:

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

在視圖(HAML):

#foo{@foo_attr} 

在CoffeeScript的資產:

$("#foo").data("foo-1") 
$("#foo").data("foo-2") 
0

您可以編輯和添加變量到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 %> 
1

在的情況下你的JavaScript數據失控,用坤創業板仍是首選方式甚至在2015年。在設置好後,您可以通過簡單地將數據分配給rails中的gon對象來將數據傳遞到JavaScript文件。

(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"}]; 

您可以閱讀關於Gon或Ryan Bate的截屏視頻中的其他兩個rails-javascript頻道的更詳細的實現細節。
http://railscasts.com/episodes/324-passing-data-to-javascript

相關問題