web-dev-qa-db-fra.com

Rails 3.1 pipeline d'actifs: comment charger des scripts spécifiques au contrôleur?

Si je génère un nouveau contrôleur en Rails 3.1, un fichier javascript avec le nom du contrôleur sera également ajouté automatiquement. Premièrement, je pensais que ce fichier javascript ne sera utilisé que lorsque le contrôleur associé sera appelé .

Par défaut, il y a l'instruction //= require_tree . dans le application.js- fichier, qui inclut tous les fichiers javascript de son arborescence.

Comment pourrais-je charger uniquement le script spécifique au contrôleur?

76
Mike Bevz

Pour charger uniquement le fichier name_of_the_js_file.js nécessaire:

  1. retirer le //=require_tree de application.js

  2. conserver votre fichier js (que vous souhaitez charger lorsqu'une page spécifique est chargée) dans le pipeline d'actifs

  3. ajouter un assistant dans application_helper.rb

    def javascript(*files)
      content_for(:head) { javascript_include_tag(*files) }
    end
    
  4. céder dans votre mise en page:

    <%= yield(:head) %>
    
  5. ajoutez ceci dans votre fichier de vue:

    <% javascript 'name_of_the_js_file' %>
    

Alors ça devrait aller

122
Nguyen Chien Cong

Une solution élégante pour cela est d'exiger controller_name dans votre javascript_include_tag

voir http://apidock.com/Rails/ActionController/Metal/controller_name/class

<%= javascript_include_tag "application", controller_name %>

controller_name.js sera chargé et est également dans l'actif, vous pouvez donc avoir besoin d'autres fichiers d'ici.

Exemple, rendre l'index des voitures # donnera

<%= javascript_include_tag "application", "cars" %>

où cars.js peut contenir

//= require wheel
//= require tyre

Prendre plaisir !

83
albandiguer

J'inclus toujours cela dans mes fichiers de mise en page. Il peut mettre votre js en action

<%= javascript_include_tag params[:controller] if AppName::Application.assets.find_asset("#{params[:controller]}.js") %>
<%= javascript_include_tag "#{params[:controller]}_#{params[:action]}"  if AppName::Application.assets.find_asset("#{params[:controller]}_#{params[:action]}.js") %>
28
Le Duc Duy

Votre problème peut être résolu de différentes manières.

Ajouter les actifs dynamiquement

Veuillez considérer que ce n'est pas une bonne solution pour le mode de production, car les spécificités de votre contrôleur ne seront pas précompilées!

  1. Ajoutez à notre assistant d'application la méthode suivante:

    module ApplicationHelper
        def include_related_asset(asset)
        #          v-----{Change this}
            if !YourApp::Application.assets.find_asset(asset).nil?
                case asset.split('.')[-1]
                    when 'js'
                        javascript_include_tag asset
                    when 'css'
                        stylesheet_link_tag asset
                end
            end
        end
    end
    
  2. Appelez la méthode d'assistance dans votre fichier layout-:

    <%= include_related_asset(params[:controller].to_param + '_' + params[:action].to_param . 'js') %>
    
  3. Créez des ressources spécifiques pour vos actions de contrôleur. Par exemple. controller_action.js

N'oubliez pas de remplacer YourApp par le nom de votre application.

Utilisez yield

  1. Ajouter <%= yield :head%> à votre tête de mise en page
  2. Inclure vos actifs à partir de vos vues d'action:

    <% content_for :head do %>
    <%= javascript_include_tag 'controller_action' %>
    <% end %>
    

Veuillez consulter les Rails guides pour plus d'informations.

6
Robin

J'aime la solution d'Albandiguer . Avec lequel j'ai trouvé que les actifs javascript/coffeescript ne sont pas précompilés individuellement. Ce qui provoque toutes sortes d'erreurs en essayant d'utiliser javascript_path. Je partagerai ma solution à ce problème après avoir abordé un problème mentionné par quelques personnes dans ses commentaires. Il s'agit principalement d'un ensemble partiel de contrôleurs nommés fichiers JavaScript.

J'ai donc construit un assistant d'application pour détecter si le fichier existe dans le répertoire javascript quelle que soit l'extension .coffee/.js:

module ApplicationHelper
  def javascript_asset_path(basename)
    Sprockets::Rails::Helper.assets.paths.select{|i|
      i =~ /javascript/ and i =~ /#{Rails.root}/
    }.each do |directory|
      if Dir.entries(directory).map {|i| i.split('.')[0]}.compact.
          include? basename
        return File.join(directory, basename)
      end
    end
    nil
  end
end

Cette méthode renverra le chemin d'accès complet au fichier javascript s'il existe. Sinon, il renvoie zéro. Donc, après le commentaire de Pencilcheck, vous pouvez ajouter cette méthode pour une inclusion conditionnelle:

<%= javascript_include_tag(controller_name) if javascript_asset_path(controller_name) %>

Et maintenant, vous avez une inclusion conditionnelle appropriée. Passons maintenant à la question des actifs précompilés. Généralement pour l'optimisation vous ne voulez pas que les actifs soient précompilés individuellement. Vous pouvez cependant le faire si vous devez:

# Live Compilation
config.assets.compile = true

Vous pouvez ajouter ceci à votre fichier de configuration d'environnement. Testez-le d'abord dans votre fichier d'environnement de développement. Encore une fois, ce n'est pas souhaitable. Le pipeline d'actifs Rails utilise Sprockets pour tout optimiser:

Sprockets charge les fichiers spécifiés, les traite si nécessaire, les concatène en un seul fichier, puis les compresse (si Rails.application.config.assets.compress est vrai). En servant un fichier plutôt que plusieurs, le temps de chargement des pages peut être considérablement réduit car le navigateur fait moins de demandes. La compression réduit également la taille des fichiers, permettant au navigateur de les télécharger plus rapidement.

VEUILLEZ LIRE la documentation pour plus de détails sur la mécanique de Sprockets (Asset Pipeline) http://guides.rubyonrails.org/asset_pipeline. html

Les actifs ne sont pas précompilés individuellement. Par exemple quand j'essaye:

<%= javascript_include_tag 'event' %>

Je reçois:

Sprockets :: Rails :: Helper :: AssetFilteredError: Les actifs sont filtrés et ne seront pas servis: ajoutez Rails.application.config.assets.precompile += %w( event.js ) à config/initializers/assets.rb Et redémarrez votre serveur

Ainsi, vous pouvez inclure les actifs à précompiler individuellement. Nous avons juste besoin d'ajouter le contrôleur approprié nommé fichiers javascript dans notre initialiseur d'actifs. Eh bien, nous pouvons le faire par programme.

Pour obtenir une liste de noms de contrôleurs, j'utiliserai l'exemple de l'écologiste :

all_controllers =  Dir[
    Rails.root.join('app/controllers/*_controller.rb')
  ].map { |path|
    path.match(/(\w+)_controller.rb/); $1
  }.compact

Et maintenant, pour obtenir le nom de tous les fichiers javascript qui correspondent au nom de base du nom du contrôleur, vous pouvez utiliser ce qui suit:

javascripts_of_controllers = Sprockets::Rails::Helper.assets.paths.select{|a_path|
    a_path =~ /javascript/ and a_path =~ /#{Rails.root}/
  }.map {|a_path|
    Dir.entries(a_path)
  }.flatten.delete_if {|the_file|
    !the_file['.js']
  }.collect {|the_file|
    the_file if all_controllers.any? {|a_controller| the_file[a_controller]}
  }

Ensuite, vous pouvez essayer:

# config/initializers/assets.rb
Rails.application.config.assets.precompile += javascripts_of_controllers

Cela vous donnera une liste de tous les fichiers javascript, sans chemin de répertoire, qui correspondent au nom de votre contrôleur. Notez que si le nom de votre contrôleur est pluriel, le nom javascript devrait également l'être. Notez également que si le contrôleur est au singulier et que le fichier javascript est au pluriel, il sera toujours inclus car the_file[a_controller] Réussira sur une correspondance partielle.

N'hésitez pas à essayer ceci dans votre paramètre Rails.application.config.assets.precompile. Je sais que cela vous donne la liste des fichiers correctement. Mais je vous laisse le tester. Faites-moi savoir s'il y a des nuances impliquées dans la précompilation de cette façon, comme je suis curieux.

Pour une explication très approfondie sur la précompilation des ressources, consultez ce blog: http://www.sitepoint.com/asset-precompile-works-part/

3
6ft Dan

J'ai récemment trouvé une approche simple pour utiliser des scripts générés pour un contrôleur spécifique. J'utilise pour cette solution gem gon . Ajoutez un contrôleur:

class HomesController < ApplicationController
  before_filter :remember_controller

  private

  def remember_controller
    gon.controller = params[:controller]
  end
end

Après cela, ouvrez votre homes.js.cofee et ajoutez au début du fichier:

jQuery ->
  if gon.controller == "sermons"
    # Place all functions here...

C'est tout.

1
ExiRe