Rails: переменная экземпляра контроллера доступа в файле ресурсов CoffeeScript или JavaScript - PullRequest
38 голосов
/ 15 декабря 2011

В Rails 3.1 невозможно получить доступ к переменным экземпляра контроллера в файле актива js.erb или coffee.erb, используя синтаксис, такой как <% = @foo%>, где @foo установлен в контроллере. Тогда возникает вопрос, как лучше всего передать переменные контроллера в ресурсы CoffeeScript или JavaScript.

Этот вопрос как бы задавался в нескольких запутанных формах на форуме, но моя точка зрения на то, чтобы спросить его снова, - это место, где все рекомендации собраны вместе, а предоставленный код прост и удобочитаем. Также обратите внимание, что я специально ссылаюсь на ресурсы, а не на просмотр файлов ответов.

Ответы [ 6 ]

27 голосов
/ 15 декабря 2011

несколькими способами, которые я делал в прошлом

, помещать данные в скрытые поля, получать доступ к данным в 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")

другой вариант: загружать данные в jsструктура данных в erb, доступ к ней из 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}"

Я не большой поклонник создания данных javascript из ruby ​​в erb, как это, что-то в этом просто кажется неправильным - хотя это может быть эффективным

и другой вариант: совершить ajax-вызов и получить данные по запросу с сервера

Меня также интересуют другие идеи и подходы

9 голосов
/ 14 мая 2012

Существует действительно хороший рельсовый состав и совсем недавно (февраль 2012 г.) по этой конкретной теме: # 324 Передача данных в JavaScript

Показывает 3 способа: тег сценария, атрибут данных и гем Gon. Я думаю, что Хаус покрыл все доступные методы. Я хотел бы только отметить, что использование вызова AJAX лучше всего использовать, когда у вас большой объем данных, динамических данных или их комбинации.

5 голосов
/ 06 июня 2012

Вместо того, чтобы использовать скрытое поле, я решил добавить атрибут данных в div контейнера, который jquery может получить.

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

тогда jquery для доступа к нему

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

Мне кажется, это самый чистый способ передачи данных в javascript. После того, как не нашли способа передать переменную в файл сценария кофе с конвейером ресурсов rails от контроллера. Это метод, который я сейчас использую. Не могу дождаться, пока кто-нибудь установит путь контроллера с рельсами, которые будут лучшими.

3 голосов
/ 09 ноября 2012

В контроллере:

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

В представлении (HAML):

#foo{@foo_attr}

В активе CoffeeScript:

$("#foo").data("foo-1")
$("#foo").data("foo-2")
1 голос
/ 18 февраля 2015

В ситуациях, когда ваши данные javascript выходят из-под контроля, использование gon gem по-прежнему является предпочтительным способом использования рельсов даже в 2015 году. После настройки 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 или двух других каналов rails-javascript вы можете прочитать из скриншота Райана Бэйта.
http://railscasts.com/episodes/324-passing-data-to-javascript

0 голосов
/ 09 июля 2013

Вы можете редактировать и добавлять переменные в массив 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 %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...