28 votes

Rails: accéder à la variable d'instance du contrôleur dans un fichier d'actif CoffeeScript ou JavaScript

Dans les Rails 3.1 il n'est pas possible de contrôleur d'accès aux variables d'instance dans un actif js.erb ou de café.erb fichier en utilisant la syntaxe <%= @foo %>, où @foo est définie dans le contrôleur. Alors la question est de savoir quels sont les meilleurs moyens pour transmettre des variables de contrôleur de CoffeeScript ou JavaScript actifs.

Cette question a été posée à de multiples formes alambiquées sur le forum, mais de mon point de demander qu'il est encore une fois d'avoir un endroit où toutes les recommandations sont réunis, et le code fourni est simple et lisible. Notez également que je suis en se référant spécifiquement aux actifs et de ne pas afficher les fichiers de réponse.

18voto

house9 Points 9240

un couple de façons que j'ai fait dans le passé

mettre les données dans des champs cachés, accès 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 des données dans js structure de données dans erb, y accéder à partir 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 javascript données de ruby dans erb comme ça, quelque chose qu'elle se sent juste mal -, il peut être efficace si

et une autre option: faire un appel ajax et d'obtenir les données sur la demande à partir du serveur

Je suis également intéressé à d'autres idées et d'approches

8voto

Max Points 1836

Il y a un casting vraiment sympa et assez récent (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 qu'il est préférable d'utiliser un appel AJAX lorsque vous avez un grand volume de données, des données dynamiques ou une combinaison des deux.

4voto

Dave Robertson Points 175

Plutôt que d'utiliser un champ caché, j'ai choisi d'ajouter un attribut de données de la div conteneur qui jquery peut prendre jusqu'à.

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

alors le jquery pour y accéder

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

Je crois que c'est la façon la plus propre de passer des données à javascript. Après avoir trouvé aucun moyen de passer une variable à un café fichier de script avec les rails asset pipeline à partir d'un contrôleur. C'est la méthode que j'utilise maintenant. Ne peut pas attendre jusqu'à ce que quelqu'un fait de configurer le contrôleur de chemin avec des rails qui sera le meilleur.

3voto

michau Points 106

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

-1voto

Archonic Points 1476

Vous pouvez modifier et ajouter des variables au tableau de paramètres du 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 %>
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X