La meilleure façon d'ajouter JavaScript spécifique à une page dans une application Rails 3?

Rails 3 a quelques JavaScript discret qui est assez cool.

mais je me demandais quelle était la meilleure façon d'inclure JavaScript supplémentaire pour une page particulière.

par exemple, où j'aurais pu faire auparavant:

<%= f.radio_button :rating, 'positive', :onclick => "$('some_div').show();" %>

nous pouvons maintenant le rendre discret avec quelque chose comme

<%= f.radio_button :rating, 'positive' %>

# then in some other file
$('user_rating_positive').click(function() {
  $('some_div').show();
}

donc je suppose que ma question Est où/comment inclure ce JavaScript? Je ne veux pas remplir vers le haut du fichier application.js parce que ce JavaScript ne s'applique qu'à cette vue. Dois-je inclure un fichier JavaScript personnalisé pour chaque page d'une façon ou d'une autre, ou le coller dans une variable d'instance que l'en-tête Recherche?

156
demandé sur Xufox 2010-08-09 09:42:34

10 réponses

ce que j'aime faire est d'inclure le Javascript Per-view dans un bloc content_for :head et ensuite yield à ce bloc dans votre mise en page d'application. Par exemple

Si c'est assez court puis:

<% content_for :head do %>
  <script type="text/javascript">
    $(function() {
      $('user_rating_positve').click(function() {
        $('some_div').show();
      }
    });
  </script>
<% end %>

ou, si elle est plus longue, alors:

<% content_for :head do %>
  <script type="text/javascript">
    <%= render :partial => "my_view_javascript"
  </script>
<% end %>

puis, dans votre fichier de mise en page

<head>
  ...
  <%= yield :head %>
</head>
148
répondu bjg 2011-11-29 18:57:53

si vous voulez inclure javascript juste sur une page, vous pouvez l'inclure sur la page inline bien sûr, mais si vous voulez grouper votre javascript et profiter de la réserve de ressources, minified js etc, il est possible de le faire et d'avoir des actifs js supplémentaires qui sont combinés et chargés seulement sur des pages spécifiques en divisant vos js en groupes qui ne s'appliquent que dans certains contrôleurs/vues/sections du site.

déplacez votre js en actifs dans des dossiers, avec un un fichier de manifeste séparé pour chacun, donc si vous aviez une bibliothèque JS admin qui n'est utilisée que sur le backend, vous pourriez faire ceci:

  • actif
    • javascripts
      • admin
        • ...js
      • admin.js (manifeste pour le groupe admin)
      • de l'application.js (manifeste pour l'application globale du groupe)
      • global
        • ...js

dans la demande existante.js

//= require jquery
//= require jquery_ujs
//= require_tree ./global // requires all js files in global folder

dans une nouvelle admin.js fichier manifeste

//= require_tree ./admin // requires all js files in admin folder

assurez-vous que ce nouveau manifeste js est chargé en éditant config/production.rb

config.assets.precompile += %w( admin.js )

ensuite, ajustez la mise en page pour que vous puissiez inclure des js supplémentaires pour le titre de la page.:

<%= content_for :header %>   

puis dans les vues où vous voulez inclure ce groupe spécifique js (ainsi que le groupe d'application normal) et / ou toute page spécifique js, css etc:

<% content_for :header do %>
  <%= javascript_include_tag 'admin' %>  
<% end %>

Vous pouvez bien sûr faire la même chose avec du css et du groupe d'une manière similaire pour appliquer qu'à certaines zones du site.

102
répondu Kenny Grant 2013-02-22 12:34:04

je préfère la suivante...

dans votre Helper application_.dossier rb

def include_javascript (file)
    s = " <script type=\"text/javascript\">" + render(:file => file) + "</script>"
    content_for(:head, raw(s))
end

et ensuite dans votre vue particulière (app/vues/livres/index.HTML.erb dans cet exemple)

<% include_javascript 'books/index.js' %>

... semble fonctionner pour moi.

11
répondu cailinanne 2011-05-17 18:41:26

ces réponses m'ont beaucoup aidé! Si quelqu'un veut un peu plus...

  1. vous devez mettre javascripts dans les manifestes si vous voulez qu'ils précompilé. Cependant, si vous avez besoin de tous les fichiers javascript de application.js.coffee , alors tous les javacsripts seront chargés à chaque fois que vous naviguez vers une page différente, et le but de faire des javasripts spécifiques à une page sera rejeté.

par conséquent, vous devez créer votre propre le fichier du Manifeste (p. ex. speciifc.js ) qui exigera tous les fichiers javascript propres à la page. Modifier aussi require_tree de application.js

app/assets/javascripts / application.js

//= require jquery
//= require jquery_ujs
//= require_tree ./global

app/assets/javascripts / specific.js

//= require_tree ./specific

puis dans votre environments/production.rb ajouter ce manifeste à la liste précompilée avec l'option de configuration,

config.assets.precompile += %w( specific.js )

fait! Tous les javascripts partagés qui devraient toujours être chargés seront placés dans le dossier app/assets/javascripts/global , et les javascripts page-spcifiques dans app/assets/javascripts/specific . Vous pouvez simplement appeler le JavaScript spécifique à la page de la vue comme

<%= javascript_include_tag "specific/whatever.js" %> //.js est facultatif.

C'est suffisant, mais j'ai voulu faire un usage de javascript_include_tag params[:controller] . Lorsque vous créez des contrôleurs, un fichier coffeescript associé est généré dans app/assets/javascripts comme d'autres personnes mentionnées. Il y a vraiment controller-specific javasripts, qui sont chargés seulement lorsque l'utilisateur atteint la vue controller spécifique.

ainsi j'ai créé un autre manifeste controller-specific.js

app/assets/javasripts/controller-specific.js

//= require_directory .

This inclura tous les coffeescripts générés automatiquement associés aux contrôleurs. De plus, vous devez l'ajouter à la liste précompilée.

config.assets.precompile += %w( specific.js controller-specific.js )

11
répondu Maximus S 2013-06-12 03:10:10

si vous ne voulez pas utiliser le pipeline de ressources ou le solutions de rechange complexes pour obtenir cette page javascript spécifique nécessaire (je comprends), la manière la plus simple et la plus robuste, qui atteint la même que les réponses ci-dessus, mais avec moins de code est juste à utiliser:

<%= javascript_include_tag "my_javascipt_file" %>

Note: cela nécessite une requête http de plus par balise include que les réponses qui utilisent content_for :head

9
répondu AJP 2017-05-23 10:31:30

regardez pluggable_js gem. Vous trouverez peut-être cette solution plus facile à utiliser.

7
répondu peresleguine 2013-07-25 12:58:58

ma compréhension est que le pipeline de l'actif est destiné à diminuer le temps de charge de la page en masquant tous vos js ensemble dans un fichier (miniifié). Bien que cela puisse sembler répugnant à première vue, c'est en fait une fonctionnalité qui existe déjà dans les langues populaires comme C et Ruby. Des choses comme" include " tags sont destinés à empêcher l'inclusion multiple d'un fichier, et à aider les programmeurs à organiser leur code. Quand vous écrivez et compilez un programme en C, tout ce code est présent dans chaque partie de votre exécution du programme, mais les méthodes ne sont chargées en mémoire que lorsque ce code est utilisé. En un sens, un programme compilé n'inclut rien pour garantir que le code est bien modulaire. Nous rendons le code modulaire en écrivant nos programmes de cette façon, et le système d'exploitation charge seulement dans la mémoire les objets et les méthodes dont nous avons besoin pour une localité donnée. Y a-t-il même une "inclusion spécifique à la méthode"? Si votre application rails est reposant, c'est essentiellement ce que vous demandez.

si vous écrivez votre javascript de façon à augmenter le comportement des éléments HTML sur la page, alors ces fonctions sont 'spécifiques à la page' par conception. S'il y a un code compliqué que vous avez écrit de telle manière qu'il sera exécuté quel que soit son contexte, peut-être envisager de lier ce code à un élément html de toute façon (vous pouvez utiliser la balise body, comme décrit dans la Garber-méthode irlandaise ). Si une fonction s'exécute conditionnellement, la performance sera probablement plus petit que toutes ces balises de script supplémentaires.

je pense utiliser le paloma gem, comme décrit dans le rails apps project . Ensuite, vous pouvez rendre votre javascript spécifique à la page en incluant des fonctions spécifiques à la page dans un appel paloma:

Paloma.callbacks['users']['new'] = function(params){
    // This will only run after executing users/new action
    alert('Hello New Sexy User');
}; 

vous utilisez des rails, donc je sais que vous aimez les gemmes:)

3
répondu Ziggy 2013-03-29 22:08:39

vous ne devriez pas charger vos fichiers JS ou CSS en dehors du pipeline de l'actif parce que vous perdez sur les caractéristiques importantes qui rendent les Rails si grands. Et tu n'as pas besoin d'une autre pierre. Je crois qu'utiliser le moins de gemmes possible, et utiliser une gemme n'est pas nécessaire ici.

ce que vous voulez est connu comme" Javascript spécifique au contrôleur "("Javascript spécifique à l'Action est inclus au bas). Cela vous permet de charger un fichier JavaScript spécifique pour un contrôleur spécifique. Essayer de connecter votre Javascript à une vue est en quelque sorte... en arrière et ne suit pas le modèle de conception MVC. Vous voulez l'associer à vos Controllers ou actions à l'intérieur de vos Controllers.

malheureusement, pour quelque raison que ce soit, Rails devs a décidé que par défaut, chaque page chargera chaque fichier JS Situé dans votre répertoire assets. Pourquoi ils ont décidé de faire cela au lieu d'activer par défaut "Javascript spécifique au contrôleur" Je ne le saurai jamais. Cela se fait par le biais de la application.fichier js, qui comprend la ligne de code suivante par défaut:

//= require_tree .

il s'agit d'une directive . C'est ce que sprockets utilise pour charger chaque fichier JS dans le répertoire assets/javascripts. Par défaut, sprockets charge automatiquement l'application.js et de l'application.css, et la directive require_tree charge chaque fichier JS et Coffee dans leurs répertoires respectifs.

NOTE: quand vous échafaudez (si vous n'êtes pas un échafaudage, c'est maintenant le bon moment pour commencer), les Rails génèrent automatiquement un fichier coffee pour vous, pour le contrôleur de cet échafaudage. Si vous voulez qu'il génère un standard js fichier au lieu d'un café fichier, puis supprimer le coffee gem qui est activé par défaut dans votre Gemfile , et votre échafaud va créer des fichiers JS à la place.

Ok, donc la première étape pour activer "Controller Specific Javascript" est de supprimer le code require_tree de votre application.le fichier js, ou le changer dans un dossier dans votre répertoire assets/javascripts si vous avez encore besoin de fichiers JS globaux. C'Est-À-Dire:

//= require_tree ./global

Étape 2: Allez dans votre config/initializers/actifs.RB, et ajouter ce qui suit:

%w( controllerone controllertwo controllerthree ).each do |controller|
  Rails.application.config.assets.precompile += ["#{controller}.js", "#{controller}.css"]
end

insérer le contrôleur les noms que vous voulez.

Étape 3: remplacer le javascript_include_tag dans votre application.HTML.erb fichier avec ceci (notez les params[:contrôleur]:

<%= javascript_include_tag 'application', params[:controller], 'data-turbolinks-track': 'reload' %>

redémarrez votre serveur et viola! Le fichier JS généré avec votre échafaudage ne se chargera que lorsque ce contrôleur sera appelé.

besoin de charger un fichier JS spécifique sur une ACTION spécifique dans votre contrôleur , I. E. /articles/Nouveau ? Faites ceci à la place:

de l'application.HTML.erb :

<%= javascript_include_tag "#{controller_name}/#{action_name}" if AppName::Application.assets.find_asset("#{controller_name}/#{action_name}") %>

config/initializers/assets.rb :

config.assets.precompile += %w(*/*)

ajoutez ensuite un nouveau dossier avec le même nom que votre contrôleur dans votre dossier ACTIFS/javascripts et mettez votre fichier js avec le même nom que votre action à l'intérieur. Il le chargera ensuite sur ce spécifique action.

3
répondu Erick Maynard 2017-10-03 03:50:21

Ok donc peut-être que c'est comme le pire travail autour jamais mais je crée une méthode de contrôleur qui vient de rendre le .fichier js

contrôleur

def get_script
   render :file => 'app/assessts/javascripts/' + params[:name] + '.js'
end
def get_page
   @script = '/' + params[:script_name] + '.js?body=1'
   render page
end

Vue

%script{:src => @script, :type => "text/javascript"}

si, pour une raison quelconque, nous ne voulons pas faire cela, alors laissez-moi savoir.

1
répondu Bill 2012-11-15 22:00:05

la façon préférée d'ajouter JS est dans le pied de page, donc vous pouvez le faire de cette façon:

.HTML.erb:

<% content_for :footer_js do %>
   This content will show up in the footer section
<% end %>

layouts/de l'application.HTML.erb

<%= yield :footer_js %>
1
répondu Syed 2014-09-22 08:21:46