Rieles: variable de instancia de controlador de acceso en CoffeeScript o archivo de activos de JavaScript

En Rails 3.1 no es posible acceder a las variables de instancia del controlador en un archivo de activos js.erb o coffee.erb utilizando una syntax como , donde @foo está establecido en el controlador. Entonces, la pregunta es cuáles son las mejores formas de pasar variables de controlador a CoffeeScript o activos de JavaScript.

Esta pregunta ha sido formulada en múltiples formas intrincadas en el foro, pero lo que quiero decir es que tengo un lugar donde todas las recomendaciones se reúnen, y el código proporcionado es simple y legible. También tenga en cuenta que me refiero específicamente a los activos y no a los archivos de respuestas.

un par de formas en que he hecho esto en el pasado

poner los datos en campos ocultos, acceder a los datos en 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") 

otra opción: cargar datos en la estructura de datos js en erb, acceder desde js / coffee

 <% content_for(:head) do %>  <% end %> # coffee for foo in window.App.Data.fooList console.log "#{foo.id}, #{foo.first_name} #{foo.last_name}" 

No soy un gran admirador de la construcción de datos de javascript desde Ruby en erb como este, algo sobre eso simplemente se siente mal, aunque puede ser efectivo

y otra opción: hacer una llamada ajax y obtener los datos a pedido del servidor

También estoy interesado en otras ideas y enfoques

Hay un reparto ferroviario realmente bueno y bastante reciente (febrero de 2012) sobre este tema específico: # 324 Pasar datos a JavaScript

Muestra 3 formas: una etiqueta de script, un atributo de datos y la gem Gon. Creo que House cubrió todas las técnicas disponibles. Solo mencionaría que usar una llamada AJAX se usa mejor cuando tiene un gran volumen de datos, datos dynamics o una combinación de ambos.

En lugar de utilizar un campo oculto, elegí agregar un atributo de datos al contenedor div que jquery puede recoger.

 

entonces el jquery para acceder

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

Siento que esta es la forma más limpia de pasar datos a JavaScript. Después de haber encontrado ninguna forma de pasar una variable a un archivo de script de café con la canalización de activos de los raíles desde un controlador. Este es el método que ahora uso. No puedo esperar hasta que alguien configure el controlador con Rails que serán los mejores.

En el controlador:

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

En la vista (HAML):

 #foo{@foo_attr} 

En el activo de CoffeeScript:

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

En situaciones en las que los datos de su javascript se salgan de control, el uso de la gem gon sigue siendo la forma preferida de usar Rails, incluso en 2015. Después de configurarlo, puede pasar datos a sus archivos javascript simplemente asignando los datos a el objeto gon en Rails.

 (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)  

Puede leer detalles de implementación más detallados en Gon o en los otros dos canales de rails-javascript del screencast de Ryan Bate.
http://railscasts.com/episodes/324-passing-data-to-javascript

Puede editar y agregar variables a la matriz params en el controlador y luego acceder a ellas en response.js.erb. Aquí hay un ejemplo con 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 

Y aquí hay un ejemplo que acompaña a 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 %>