webentwicklung-frage-antwort-db.com.de

Rails 3.1-Asset-Pipeline: Wie lade ich controller-spezifische Skripte?

Wenn ich in Rails 3.1 einen neuen Controller generiere, wird automatisch auch eine Javascript-Datei mit dem Namen des Controllers hinzugefügt. Erstens dachte ich, diese Javascript-Datei wird nur verwendet, wenn der zugehörige Controller aufgerufen wird .

Standardmäßig gibt es die Anweisung //= require_tree . in dem application.js- Datei, die jede Javascript-Datei in ihrem Baum enthält.

Wie kann ich nur das Controller-spezifische Skript laden?

76
Mike Bevz

So laden Sie nur die Datei name_of_the_js_file.js:

  1. entferne den //=require_tree aus application.js

  2. behalten Sie Ihre js-Datei (die Sie laden möchten, wenn eine bestimmte Seite geladen wird) in der Asset-Pipeline

  3. füge einen Helfer in application_helper.rb hinzu

    def javascript(*files)
      content_for(:head) { javascript_include_tag(*files) }
    end
    
  4. geben Sie in Ihr Layout ein:

    <%= yield(:head) %>
    
  5. fügen Sie dies in Ihre Ansichtsdatei ein:

    <% javascript 'name_of_the_js_file' %>
    

Dann sollte es ok sein

122

Eine elegante Lösung hierfür besteht darin, controller_name in Ihrem javascript_include_tag anzugeben

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

<%= javascript_include_tag "application", controller_name %>

controller_name.js wird geladen und befindet sich auch im Asset, sodass Sie von hier aus andere Dateien anfordern können.

Beispiel: Beim Rendern von cars # index erhalten Sie

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

wo cars.js enthalten kann

//= require wheel
//= require tyre

Genießen !

83
albandiguer

Ich füge dies immer in meine Layoutdateien ein. Es kann Ihr js zum Handeln übergehen

<%= 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

Ihr Problem kann auf verschiedene Arten gelöst werden.

Fügen Sie die Assets dynamisch hinzu

Bitte beachten Sie, dass dies keine gute Lösung für den Produktionsmodus ist, da Ihre Steuerungsspezifikationen nicht vorkompiliert werden!

  1. Fügen Sie unserem Application Helper die folgende Methode hinzu:

    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. Rufen Sie die Hilfsmethode in Ihrer layout- Datei auf:

    <%= include_related_asset(params[:controller].to_param + '_' + params[:action].to_param . 'js') %>
    
  3. Erstellen Sie spezifische Assets für Ihre Controller-Aktionen. Z.B. controller_action.js

Bitte vergessen Sie nicht, YourApp in den Namen Ihrer App zu ändern.

Benutze yield

  1. Hinzufügen <%= yield :head%> zu Ihrem Layoutkopf
  2. Beziehen Sie Ihre Assets aus Ihren Aktionsansichten ein:

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

Weitere Informationen finden Sie in den Schienenführungen .

6
Robin

Ich mag albandiguers Lösung . Womit ich festgestellt habe, dass Javascript/Coffeescript-Assets nicht einzeln vorkompiliert werden. Wodurch alle möglichen Fehler bei der Verwendung von javascript_path Verursacht werden. Ich werde meine Lösung für dieses Problem mitteilen, nachdem ich ein Problem angesprochen habe, das in seinen Kommentaren erwähnt wurde. Hauptsächlich mit nur einem Teil der Controller namens JavaScript-Dateien.

Deshalb habe ich einen Anwendungs-Helfer erstellt, um festzustellen, ob die Datei im Javascript-Verzeichnis vorhanden ist, unabhängig von der Erweiterung .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

Diese Methode gibt den vollständigen Pfad zur Javascript-Datei zurück, falls vorhanden. Andernfalls wird nil zurückgegeben. Wenn Sie also Pencilchecks Kommentar folgen, können Sie diese Methode für ein bedingtes Include hinzufügen:

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

Und jetzt haben Sie eine ordnungsgemäße bedingte Einbeziehung. Nun zur Ausgabe vorkompilierter Assets. Im Allgemeinen für die Optimierung Sie möchten nicht, dass Assets vorkompiliert werden einzeln. Sie können es jedoch tun, wenn Sie müssen:

# Live Compilation
config.assets.compile = true

Sie können dies zu Ihrer Umgebungskonfigurationsdatei hinzufügen. Testen Sie es zuerst in Ihrer Entwicklungsumgebungsdatei. Auch dies ist nicht ratsam. Die Rails Asset-Pipeline verwendet Sprockets, um alles zu optimieren:

Sprockets lädt die angegebenen Dateien, verarbeitet sie bei Bedarf, verknüpft sie zu einer einzigen Datei und komprimiert sie dann (wenn Rails.application.config.assets.compress den Wert true hat). Durch das Bereitstellen einer Datei anstelle vieler Dateien kann die Ladezeit von Seiten erheblich reduziert werden, da der Browser weniger Anforderungen stellt. Durch die Komprimierung wird auch die Dateigröße reduziert, sodass der Browser sie schneller herunterladen kann.

BITTE LESEN Sie die Dokumentation für weitere Details der Mechanik von Kettenräder (Asset Pipeline) http://guides.rubyonrails.org/asset_pipeline. html

Assets werden nicht einzeln vorkompiliert. Zum Beispiel, wenn ich versuche:

<%= javascript_include_tag 'event' %>

Ich bekomme:

Sprockets :: Rails :: Helper :: AssetFilteredError: Asset wurde herausgefiltert und wird nicht bedient: Fügen Sie Rails.application.config.assets.precompile += %w( event.js ) zu config/initializers/assets.rb Hinzu und starten Sie Ihren Server neu

So können Sie angeben, welche Assets einzeln vorkompiliert werden sollen. Wir müssen nur den entsprechenden Controller mit dem Namen Javascript-Dateien in unseren Asset-Initialisierer aufnehmen. Nun, wir können dies programmatisch tun.

Um eine Liste der Controllernamen zu erhalten, verwende ich Beispiel von ecoologic :

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

Und um den Namen aller Javascript-Dateien zu erhalten, die mit dem Basisnamen des Controllernamens übereinstimmen, können Sie Folgendes verwenden:

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]}
  }

Dann können Sie versuchen:

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

Dadurch erhalten Sie eine Liste aller Javascript-Dateien ohne Verzeichnispfad, die dem Namen Ihres Controllers entsprechen. Hinweis: Wenn der Name Ihres Controllers Plural ist, sollte dies auch der JavaScript-Name sein. Beachten Sie auch, dass, wenn der Controller Singular ist und die Javascript-Datei Plural ist, dies immer noch einschließt, da the_file[a_controller] Bei einer Teilübereinstimmung erfolgreich ist.

Probieren Sie dies in Ihrer Einstellung Rails.application.config.assets.precompile Aus. Ich weiß, dass Sie damit die Liste der Dateien korrekt erhalten. Aber ich überlasse es Ihnen, es zu testen. Lassen Sie mich wissen, ob die Vorkompilierung auf diese Weise Nuancen mit sich bringt, da ich neugierig bin.

Eine sehr ausführliche Erklärung zur Vorkompilierung von Assets finden Sie in diesem Blog: http://www.sitepoint.com/asset-precompile-works-part/

3
6ft Dan

Kürzlich habe ich einen einfachen Ansatz gefunden, um generierte Skripte für bestimmte Controller zu verwenden. Ich benutze für diese Lösung gem gon . Hinzufügen eines Controllers:

class HomesController < ApplicationController
  before_filter :remember_controller

  private

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

Danach öffne dein homes.js.cofee und füge am Anfang der Datei hinzu:

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

Das ist alles.

1
ExiRe