Dans Rails 3.1, il n'est pas possible d'accéder aux variables d'instance de contrôleur dans un fichier d'actif js.erb ou coffee.erb en utilisant une syntaxe telle que <% = @foo%>, où @foo est défini dans Alors, la question est de savoir quelles sont les meilleures façons de passer des variables de contrôleur aux ressources CoffeeScript ou JavaScript.
Cette question a en quelque sorte été posée sous de multiples formes compliquées sur le forum, mais mon point en la posant à nouveau est d'avoir un endroit où toutes les recommandations sont rassemblées, et le code fourni est simple et lisible. Notez également que je fais spécifiquement référence aux actifs et non aux fichiers de réponses.
un couple de façons que je l'ai fait dans le passé
mettre les données dans des champs cachés, accéder aux données en js/café
# 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")
une autre option: charger les données dans la structure de données js dans erb, y accéder depuis js/café
<% 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}"
Je ne suis pas un grand fan de la construction de données javascript à partir de Ruby en erb comme celui-ci, quelque chose à ce sujet ne semble pas correct - il peut être efficace cependant
et une autre option: passer un appel ajax et obtenir les données à la demande du serveur
Je suis également intéressé par d'autres idées et approches
Il y a une distribution ferroviaire vraiment sympa et assez récente (février 2012) sur ce sujet spécifique: # 324 Passing Data to JavaScript
Il montre 3 façons: une balise de script, un attribut de données et la gemme Gon. Je pense que la maison couvrait toutes les techniques disponibles. Je voudrais seulement mentionner que l'utilisation d'un appel AJAX est mieux utilisée lorsque vous avez un grand volume de données, des données dynamiques ou une combinaison des deux.
Plutôt que d'utiliser un champ caché, j'ai choisi d'ajouter un attribut de données à la div de conteneur que jquery peut récupérer.
<div class="searchResults" data-query="<%= @q %>"></div>
puis le jquery pour y accéder
url: "/search/get_results?search[q]=" + $(".searchResults").data("query") + "&page=" + p
Je pense que c'est le moyen le plus propre de transmettre des données à javascript. Après avoir trouvé aucun moyen de passer une variable à un fichier de script café avec le pipeline d'actifs Rails à partir d'un contrôleur. C'est la méthode que j'utilise maintenant. Je ne peux pas attendre que quelqu'un configure le façon contrôleur avec Rails ce sera le meilleur.
Dans le contrôleur:
@foo_attr = { "data-foo-1" => 1, "data-foo-2" => 2 }
Dans la vue (HAML):
#foo{@foo_attr}
Dans l'actif CoffeeScript:
$("#foo").data("foo-1")
$("#foo").data("foo-2")
Dans les situations où vos données javascript deviennent incontrôlables, l'utilisation de la gemme gon est toujours la manière préférée d'aller dans Rails, même en 2015. Après avoir configuré gon, vous pouvez transmettre des données à vos fichiers javascript en affectant simplement les données à l'objet gon dans 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)
<script>
window.gon = {};
gon.products = [{"created_at":"2015", "updated_at":"2015, "id":1, "etc":"etc"}];
Vous pouvez lire des détails d'implémentation plus détaillés sur Gon ou les deux autres canaux Rails-javascript du screencast de Ryan Bate.
http://railscasts.com/episodes/324-passing-data-to-javascript
Vous pouvez modifier et ajouter des variables au tableau de paramètres dans le contrôleur, puis y accéder dans le fichier response.js.erb. Voici un exemple avec 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
Et voici un exemple accompagnant 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 %>