À ma connaissance, tout votre JavaScript est fusionné en un seul fichier. Rails le fait par défaut lorsqu'il ajoute //= require_tree .
au bas de votre application.js
fichier manifeste.
Cela ressemble à un vrai sauveteur, mais je suis un peu préoccupé par le code JavaScript spécifique à la page. Ce code est-il exécuté sur chaque page? La dernière chose que je veux, c'est que tous mes objets soient instanciés pour chaque page alors qu'ils ne sont nécessaires que sur 1 page.
De plus, n'y a-t-il pas un potentiel de code qui se heurte aussi?
Ou placez-vous une petite script
balise au bas de la page qui appelle simplement une méthode qui exécute le code javascript de la page?
Vous n'avez donc plus besoin de require.js?
Merci
EDIT : J'apprécie toutes les réponses ... et je ne pense pas qu'ils s'attaquent vraiment au problème. Certains d'entre eux concernent le style et ne semblent pas se rapporter ... et d'autres mentionnent simplement javascript_include_tag
... qui je sais existe (évidemment ...) mais il semblerait que la voie à suivre pour Rails 3.1 consiste à récapituler tout votre JavaScript dans 1 fichier plutôt que de charger du JavaScript individuel au bas de chaque page.
La meilleure solution que je puisse trouver consiste à envelopper certaines fonctionnalités dans des div
balises avec id
s ou class
es. Dans le code JavaScript, vous vérifiez simplement si le id
ou se class
trouve sur la page, et si c'est le cas, vous exécutez le code JavaScript qui lui est associé. De cette façon, si l'élément dynamique n'est pas sur la page, le code JavaScript ne s'exécute pas - même s'il a été inclus dans le application.js
fichier massif emballé par Sprockets.
Ma solution ci-dessus a l'avantage que si un champ de recherche est inclus sur 8 des 100 pages, il ne fonctionnera que sur ces 8 pages. Vous n'aurez pas non plus à inclure le même code sur 8 des pages du site. En fait, vous n'aurez plus jamais à inclure de balises de script manuelles sur votre site.
Je pense que c'est la réponse à ma question.
la source
application.js
), et en fait la référence que vous avez fournie explique pourquoi il en est ainsi: le téléchargement est le partie la plus lente du processus d'exécution JS. De nombreux petits fichiers sont plus faciles à mettre en cache qu'un gros. Les gens de Unholy Rails ne semblent pas réaliser, alors, que leurs recommandations sont incompatibles avec les principes auxquels ils essaient de se conformer, et donc leurs recommandations ne devraient pas être prises au sérieux.Réponses:
Les documents Asset Pipeline suggèrent comment effectuer JS spécifique au contrôleur:
Lien vers: asset_pipeline
la source
page_specific_js = "#{params[:controller]}_#{params[:action]}"
et alors;javascript_include_tag page_specific_js if Rails.application.assets.find_asset page_specific_js
Pour les js spécifiques à une page, vous pouvez utiliser la solution Garber-Irish .
Ainsi, votre dossier javascripts Rails pourrait ressembler à ceci pour deux contrôleurs - voitures et utilisateurs:
Et les javascripts ressembleront à ceci:
et markup_based_js_execution contiendra du code pour l'objet UTIL, et sur l'exécution UTIL.init prête pour DOM.
Et n'oubliez pas de mettre ceci dans votre fichier de mise en page:
Je pense également qu'il est préférable d'utiliser des classes plutôt que des
data-*
attributs, pour un meilleur CSS spécifique à la page. Comme Jason Garber l'a mentionné: les sélecteurs CSS spécifiques à une page peuvent devenir très gênants (lorsque vous utilisez desdata-*
attributs)J'espère que cela t'aidera.
la source
window.varForOneController='val'
dans cette fonction d'initialisation du contrôleur. Gon gem peut également aider ici ( github.com/gazay/gon ). Il peut y avoir d'autres solutions.//= require_tree .
code JavaScript spécifique à la page et à l'utiliser. Si vous essayez activement de ne pas faire cela, alors vous vous efforcez de mauvaises pratiques.Je vois que vous avez répondu à votre propre question, mais voici une autre option:
Fondamentalement, vous faites l'hypothèse que
est requis. Ce n'est pas. N'hésitez pas à le retirer. Dans mon application actuelle, la première que je fais honnêtement avec 3.1.x, j'ai créé trois fichiers JS de premier niveau différents. Mon
application.js
fichier n'a queDe cette façon, je peux créer des sous-répertoires, avec leurs propres fichiers JS de niveau supérieur, qui incluent uniquement ce dont j'ai besoin.
Les clés sont:
require_tree
- Rails vous permet de modifier les hypothèses qu'il faitapplication.js
- tout fichier duassets/javascript
sous - répertoire peut inclure des directives de pré-processeur avec//=
J'espère que cela aide et ajoute quelques détails à la réponse de ClosureCowboy.
Sujal
la source
//= require_tree .
par//= require_directory .
afin que vous puissiez conserver tous les fichiers existants où ils se trouvent et créer de nouveaux répertoires pour les fichiers spécifiques à la page.Autre option: pour créer des fichiers spécifiques à une page ou à un modèle, vous pouvez créer des répertoires dans votre
assets/javascripts/
dossier.Votre
application.js
fichier manifeste principal pourrait être configuré pour charger ses fichiers à partir deglobal/
. Des pages ou des groupes de pages spécifiques peuvent avoir leurs propres manifestes qui chargent des fichiers à partir de leurs propres répertoires spécifiques. Sprockets combinera automatiquement les fichiers chargés parapplication.js
avec vos fichiers spécifiques à la page, ce qui permet à cette solution de fonctionner.Cette technique peut également être utilisée
style_sheets/
.la source
J'apprécie toutes les réponses ... et je ne pense pas qu'ils s'attaquent vraiment au problème. Certains d'entre eux concernent le style et ne semblent pas se rapporter ... et d'autres mentionnent simplement
javascript_include_tag
... qui je sais existe (évidemment ...) mais il semblerait que la voie à suivre pour Rails 3.1 consiste à récapituler tout votre Javascript dans 1 fichier plutôt que de charger le Javascript individuel au bas de chaque page.La meilleure solution que je puisse trouver consiste à envelopper certaines fonctionnalités dans des
div
balises avecid
s ouclass
es. Dans le code javascript. Ensuite, vous vérifiez simplement si leid
ouclass
est sur la page, et si c'est le cas, vous exécutez le code javascript qui lui est associé. De cette façon, si l'élément dynamique n'est pas sur la page, le code javascript ne s'exécute pas - même s'il a été inclus dans leapplication.js
fichier massif emballé par Sprockets.Ma solution ci-dessus a l'avantage que si un champ de recherche est inclus sur 8 des 100 pages, il ne fonctionnera que sur ces 8 pages. Vous n'aurez pas non plus à inclure le même code sur 8 des pages du site. En fait, vous n'aurez plus jamais à inclure de balises de script manuelles sur votre site, sauf pour précharger des données.
Je pense que c'est la réponse à ma question.
la source
<script>
balises manuelles . Oui, les classes et les identifiants font partie de la réponse, mais cela n'a aucun sens pour l'utilisateur de charger JavaScript que cette page particulière ne nécessite pas.Je me rends compte que je viens à cette fête un peu en retard, mais je voulais apporter une solution que j'ai utilisée récemment. Cependant, permettez-moi d'abord de mentionner ...
The Rails 3.1 / 3.2 Way (Non, monsieur. Je n'aime pas ça.)
Voir: http://guides.rubyonrails.org/asset_pipeline.html#how-to-use-the-asset-pipeline
J'inclus les éléments suivants par souci d'exhaustivité dans cette réponse, et parce que ce n'est pas une solution non viable ... bien que je ne m'en soucie pas beaucoup.
Le "Rails Way" est une solution orientée contrôleur, plutôt que d'être orientée vue comme l'auteur original de cette question l'a demandé. Il existe des fichiers JS spécifiques au contrôleur qui portent le nom de leurs contrôleurs respectifs. Tous ces fichiers sont placés dans une arborescence de dossiers qui n'est PAS incluse par défaut dans aucune des applications.js nécessitent des directives.
Pour inclure du code spécifique au contrôleur, les éléments suivants sont ajoutés à une vue.
Je déteste cette solution, mais elle est là et c'est rapide. Vraisemblablement, vous pouvez à la place appeler ces fichiers quelque chose comme "people-index.js" et "people-show.js", puis utiliser quelque chose comme
"#{params[:controller]}-index"
pour obtenir une solution orientée vue. Encore une fois, solution rapide, mais cela ne me convient pas.Ma manière d'attribut de données
Appelez-moi fou, mais je veux que TOUS mes JS soient compilés et minifiés dans application.js lorsque je déploie. Je ne veux pas avoir à me rappeler d'inclure ces petits fichiers de retardateur partout.
Je charge tout mon JS dans un fichier compact, bientôt mis en cache par le navigateur. Si un certain morceau de mon application.js doit être lancé sur une page, je laisse le HTML me le dire, pas Rails.
Plutôt que de verrouiller mon JS sur des ID d'élément spécifiques ou de joncher mon HTML avec des classes de marqueurs, j'utilise un attribut de données personnalisé appelé
data-jstags
.Sur chaque page, j'utilise - insérez ici la méthode de bibliothèque JS préférée - pour exécuter le code lorsque le DOM a terminé le chargement. Ce code d'amorçage effectue les actions suivantes:
data-jstag
Disons que j'ai défini ce qui suit quelque part dans mon application.js:
L'événement d'amorçage va appliquer les fonctions
my_autosuggest_init
etmy_hint_init
à l'entrée de recherche, la transformant en une entrée qui affiche une liste de suggestions pendant que l'utilisateur tape, ainsi que fournissant une sorte d'indice d'entrée lorsque l'entrée est laissée vide et non focalisée.À moins qu'un élément ne soit marqué
data-jstag="auto-suggest"
, le code de suggestion automatique ne se déclenche jamais. Cependant, il est toujours là, minifié et finalement mis en cache dans mon application.js pour les moments où j'en ai besoin sur une page.Si vous devez transmettre des paramètres supplémentaires à vos fonctions JS balisées, vous devrez faire preuve de créativité. Soit ajouter des attributs de paramètres de données, trouver une sorte de syntaxe de paramètre, ou même utiliser une approche hybride.
Même si j'ai un flux de travail compliqué qui semble spécifique au contrôleur, je vais juste créer un fichier pour celui-ci dans mon dossier lib, le mettre dans application.js et le marquer avec quelque chose comme 'new-thing-wizard'. Lorsque mon bootstrap atteint cette balise, mon gentil assistant sophistiqué sera instancié et exécuté. Il s'exécute pour les vues de ce contrôleur en cas de besoin, mais n'est pas autrement couplé au contrôleur. En fait, si je code correctement mon assistant, je pourrais être en mesure de fournir toutes les données de configuration dans les vues et donc être en mesure de réutiliser mon assistant plus tard pour tout autre contrôleur qui en a besoin.
Quoi qu'il en soit, c'est ainsi que j'implémente JS spécifique à une page depuis un certain temps maintenant, et cela m'a bien servi à la fois pour la conception de sites simples et pour des applications plus complexes / riches. J'espère que l'une des deux solutions que j'ai présentées ici, à ma façon ou à la manière de Rails, sera utile à quiconque rencontrera cette question à l'avenir.
la source
Cela a été répondu et accepté il y a longtemps, mais j'ai trouvé ma propre solution basée sur certaines de ces réponses et mon expérience avec Rails 3+.
Le portefeuille d'actifs est doux. Utilise le.
Tout d'abord, dans votre
application.js
fichier, supprimez//= require_tree.
Ensuite, dans votre
application_controller.rb
méthode de création d'une aide:Ensuite, dans votre
application.html.erb
fichier de mise en page, ajoutez votre nouvel assistant parmi les inclus javascript existants, préfixés avec l'raw
aide:Voila, maintenant vous pouvez facilement créer du javascript spécifique à la vue en utilisant la même structure de fichiers que vous utilisez partout ailleurs dans les rails. Collez simplement vos fichiers
app/assets/:namespace/:controller/action.js.erb
!J'espère que cela aide quelqu'un d'autre!
la source
<%= raw ... %>
retourne un 404?require_tree /
(mauvais)?Vous pouvez ajouter cette ligne dans votre fichier de mise en page (par exemple application.html.erb) pour charger automatiquement le fichier javascript spécifique au contrôleur (celui qui a été créé lorsque vous avez généré le contrôleur):
Vous pouvez également ajouter une ligne pour charger automatiquement un fichier de script par action.
Mettez simplement vos scripts de page dans une sous-répertoire nommée d'après le nom du contrôleur. Dans ces fichiers, vous pouvez inclure d'autres scripts en utilisant = require. Il serait intéressant de créer un assistant pour inclure le fichier uniquement s'il existe, afin d'éviter un échec 404 dans le navigateur.
la source
la source
Vous trouverez peut-être la gemme pluggable_js comme solution appropriée.
la source
La gemme LoadJS est une autre option:
la source
La réponse de Philip est assez bonne. Voici le code pour le faire fonctionner:
Dans application.html.erb:
<body class="<%=params[:controller].parameterize%>">
En supposant que votre contrôleur s'appelle Projets, cela générera:
<body class="projects">
Puis dans projects.js.coffee:
la source
<body>
est ipso facto incorrect. Voir mes commentaires ailleurs sur cette page.Les scripts Java ne sont fusionnés que lorsque vous demandez à Rails (Sprockets, plutôt) de les fusionner.
la source
//= require_tree .
?require_tree .
est généralement une mauvaise idée.Voici comment j'ai résolu le problème de style: (excusez le Haml)
De cette façon, je démarre tous les fichiers .css.sass spécifiques à la page avec:
De cette façon, vous pouvez facilement éviter tout affrontement. En ce qui concerne les fichiers .js.coffee , vous pouvez simplement initialiser des éléments comme;
J'espère que cela a aidé certains.
la source
$('#post > #edit') ->
semble invalide. Comment définissez-vous jQuery pour travailler dans une étendue?= javascript_include_tag "application"
et de= javascript_include_tag params[:controller]
cette façon, je peux garder le code javascript confiné sans avoir à spécifier une portée à l'intérieur du fichier.Vous pouvez également regrouper les js dans des dossiers et continuer à utiliser le pipeline d'actifs pour charger votre javascript de manière sélective en fonction de la page.
la source
Je suis d'accord avec votre réponse, pour vérifier si ce sélecteur est là, utilisez:
(personne n'a vu ajouter la solution réelle)
la source
Je ne vois pas de réponse qui rassemble vraiment tout cela et vous l'explique. Ainsi, je vais essayer de mettre meleyal , sujal (à la ClosureCowboy ), la première partie de la réponse de Ryan , et même la déclaration audacieuse de Gal à propos de Backbone.js ... tous ensemble d'une manière qui est courte et claire. Et, qui sait, je pourrais même répondre aux exigences de Marnen Laibow-Koser .
Exemples de modifications
assets / javascripts / application.js
views / layouts / application.html.erb
views / foo / index.html.erb
assets / javascripts / foo.js
actifs / javascripts / foostuff / foothis.js.coffee
Brève description
Supprimez
//= require_tree .
de application.js et répertoriez uniquement le JS que chaque page partage.Les deux lignes indiquées ci-dessus dans application.html.erb indiquent à la page où inclure application.js et votre JS spécifique à la page.
Les trois lignes montrées ci-dessus dans index.html.erb indiquent à votre vue de rechercher un JS spécifique à une page et de l'inclure dans une région de rendement nommée appelée ": javascript" (ou tout ce que vous voulez lui donner). Dans cet exemple, le contrôleur est "foo", donc Rails tentera d'inclure "foo.js" dans la région de rendement: javascript dans la présentation de l'application.
Listez votre JS spécifique à une page dans foo.js (ou quel que soit le nom du contrôleur). Liste des bibliothèques communes, un arbre, des répertoires, etc.
Gardez votre JS spécifique à une page personnalisée quelque part où vous pouvez facilement le référencer en dehors de votre autre JS personnalisé. Dans cet exemple, foo.js nécessite l'arborescence foostuff, placez-y votre JS personnalisé, comme foothis.js.coffee .
Il n'y a pas de règles strictes ici. N'hésitez pas à déplacer les choses et peut-être même à créer plusieurs régions de rendement de différents noms dans différentes dispositions si nécessaire. Cela montre juste un premier pas en avant possible. (Je ne le fais pas exactement comme cela étant donné notre utilisation de Backbone.js. Je pourrais aussi choisir de déposer foo.js dans un dossier appelé foo au lieu de foostuff mais je n'ai pas encore décidé cela.)
Remarques
Vous pouvez faire des choses similaires avec CSS et
<%= stylesheet_link_tag params[:controller] %>
cela dépasse la portée de la question.Si j'ai raté une meilleure pratique flagrante ici, envoyez-moi une note et je vais m'adapter. Rails est assez nouveau pour moi et, honnêtement, je ne suis pas très impressionné jusqu'à présent par le chaos qu'il apporte par défaut au développement de l'entreprise et tout le trafic généré par le programme Rails moyen.
la source
J'ai une autre solution qui, bien que primitive, fonctionne bien pour moi et ne nécessite aucune stratégie de chargement sélective sophistiquée. Mettez votre fonction prête pour le document nornal, mais testez ensuite l'emplacement actuel de Windows pour voir si c'est la page à laquelle votre javascript est destiné:
Cela permet toujours à tous les js d'être chargés par rails 3.x dans un petit paquet, mais ne génère pas beaucoup de surcharge ou de conflits avec les pages auxquelles le js n'est pas destiné.
la source
La réponse de ryguy est une bonne réponse, même si elle a été déclassée en points négatifs.
Surtout si vous utilisez quelque chose comme Backbone JS - chaque page a sa propre vue Backbone. Ensuite, le fichier erb n'a qu'une seule ligne de javascript en ligne qui déclenche la bonne classe d'affichage de la dorsale. Je le considère comme une seule ligne de «code de colle» et donc le fait que son inline est OK. L'avantage est que vous pouvez conserver votre "require_tree" qui permet au navigateur de mettre en cache tout le javascript.
dans show.html.erb, vous aurez quelque chose comme:
et dans votre fichier de mise en page, vous aurez besoin de:
la source
Déplacez tous vos fichiers JS commom vers un sous-dossier comme 'app / assets / javascript / global' puis dans application.js, modifiez la
//= require_tree .
ligne en//= require_tree ./global
.Maintenant, vous êtes libre de placer votre JS spécifique au contrôleur à la racine 'app / assets / javascript /' et ils ne seront pas inclus dans le JS compilé, utilisé uniquement lorsque vous les appelez via
= javascript_include_tag
sur votre contrôleur / vue.la source
Bien que vous ayez plusieurs réponses ici, je pense que votre montage est probablement le meilleur pari. Un modèle de conception que nous utilisons dans notre équipe que nous avons obtenu de Gitlab est le modèle Dispatcher. Il fait quelque chose de similaire à ce dont vous parlez, mais le nom de la page est défini dans la balise body par rails. Par exemple, dans votre fichier de mise en page, incluez simplement quelque chose comme (dans HAML):
N'ayez alors qu'une seule fermeture et une instruction switch dans votre
dispatcher.js.coffee
fichier dans votre dossier javascripts comme ceci:Tout ce que vous devez faire dans les fichiers individuels ( par exemple
products.js.coffee
oulogin.js.coffee
par exemple) est de les enfermer dans une classe, puis de globaliser ce symbole de classe afin que vous puissiez y accéder dans le répartiteur:Gitlab en a plusieurs exemples que vous voudrez peut-être fouiller au cas où vous seriez curieux :)
la source
Le projet Paloma offre une approche intéressante pour gérer le code javascript spécifique à une page.
Exemple d'utilisation de leurs documents:
la source
Étape 1. supprimer require_tree. dans votre application.js et application.css.
Étape 2. Modifiez votre application.html.erb (par défaut par rails) dans le dossier de disposition. Ajoutez "params [: contrôleur]" dans les balises suivantes.
Étape 3. Ajoutez un fichier dans config / initializers / assets.rb
références: http://theflyingdeveloper.com/controller-specific-assets-with-rails-4/
la source
Je n'ai pas essayé cela, mais il semble que ce qui suit est vrai:
si vous avez un content_for qui est javascript (par exemple avec du vrai javascript en son sein), les sprockets ne le sauraient pas et donc cela fonctionnerait de la même manière que maintenant.
si vous voulez exclure un fichier du grand paquet de javascript, vous irez dans le fichier config / sprockets.yml et modifierez les fichiers source en conséquence. Ensuite, vous devez simplement inclure les fichiers que vous avez exclus si nécessaire.
la source
Je l'ai fait précédemment en utilisant cette méthode: http://theflyingdeveloper.com/controller-specific-assets-with-rails-4/ . Super facile, s'appuie sur des contrôleurs pour sélectionner les js appropriés à charger.
la source
J'ai combiné quelques réponses en:
Aide à l'application:
layouts / application.html.haml:
la source
Premièrement: supprimer
\\=require_tree
de application.js Deuxièmement: tout votre code JS doit être attribué à/app/assets/javascritpt
et tout votre code CSS doit être localisé à/app/assets/stylesheets
la source
Suivant l'exemple de Ryan, voici ce que j'ai fait-
application.js.coffee
users.js.coffee (coffeescript spécifique au contrôleur, par exemple contrôleur: utilisateurs, action: tableau de bord)
application.html.haml
la source
eval
) si votre HTML est compromis par un serveur piraté ou un script utilisateur malveillant.Voici comment le faire, surtout si vous n'avez pas à exécuter des tonnes de bibliothèques pour votre page spécifique, mais uniquement pour exécuter plus ou moins quelques centaines de lignes de JS.
Puisqu'il est parfaitement possible d'incorporer du code Javascript dans HTML, créez simplement sous le répertoire app / views shared.js et placez-y votre code spécifique page / pages dans my_cool_partial.html.erb
Alors maintenant, où que vous vouliez, vous faites simplement:
Et c'est tout, k?
la source