Rails 3.1 Asset pipeline: jak wczytać Skrypty specyficzne dla kontrolera?

Jeśli wygeneruję nowy kontroler w Rails 3.1, również plik javascript z nazwą kontrolera zostanie dodany automatycznie. Po pierwsze, myślałem, że ten plik javascript będzie używany tylko, gdy powiązany kontroler jest wywoływany.

Domyślnie w application.js-file znajduje się instrukcja //= require_tree ., która zawiera każdy plik javascript w drzewie.

Jak mogę załadować tylko skrypt kontrolera?

Author: New Alexandria, 2011-07-04

6 answers

Aby załadować tylko niezbędny plik nazwa_of_the_js_file.plik js:

  1. Usuń //=require_tree z application.js

  2. Przechowuj plik js (który chcesz załadować po załadowaniu określonej strony) w potoku zasobów

  3. Dodaj pomocnika w application_helper.rb

    def javascript(*files)
      content_for(:head) { javascript_include_tag(*files) }
    end
    
  4. Poddaj się układowi:

    <%= yield(:head) %>
    
  5. Dodaj to do pliku widoku:

    <% javascript 'name_of_the_js_file' %>
    

Wtedy powinno być ok

 122
Author: Nguyen Chien Cong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-28 10:03:09

Eleganckim rozwiązaniem jest wymaganie controller_name w javascript_include_tag

Zobacz http://apidock.com/rails/ActionController/Metal/controller_name/class

<%= javascript_include_tag "application", controller_name %>

Controller_name.js zostanie załadowany i jest również w zasobie, więc możesz wymagać innych plików stąd.

Przykład, rendering samochodów # index DA

<%= javascript_include_tag "application", "cars" %>
Gdzie samochody.js może zawierać
//= require wheel
//= require tyre
Smacznego !
 83
Author: albandiguer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-20 20:46:55

Zawsze umieszczam to w moich plikach układu. Może skierować Twój js do działania

<%= 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
Author: Le Duc Duy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-16 16:13:35

Twój problem można rozwiązać na różne sposoby.

Dodaj aktywa dynamicznie

Proszę wziąć pod uwagę, że nie jest to dobre rozwiązanie dla trybu produkcyjnego, ponieważ dane Twojego kontrolera nie zostaną wstępnie skompilowane!

  1. Dodaj do naszego pomocnika aplikacji następującą metodę:

    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. Wywołanie metody pomocniczej w pliku layout:

    <%= include_related_asset(params[:controller].to_param + '_' + params[:action].to_param . 'js') %>
    
  3. Utwórz określone zasoby dla akcji kontrolera. Np. controller_action.js

Nie zapomnij zmienić YourApp na nazwę aplikacji.

Użycie yield

  1. Dodaj <%= yield :head%> do swojego layoutu
  2. Dołącz swoje zasoby z Twoich widoków akcji:

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

Aby uzyskać więcej informacji, zobacz prowadnice Rails.

 6
Author: Robin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-13 14:33:37

Podoba mi się rozwiązanie albandiguera. Z którym odkryłem, że zasoby javascript / coffeescript nie są indywidualnie wstępnie skompilowane. Co powoduje różnego rodzaju błędy przy użyciu javascript_path. Podzielę się moim rozwiązaniem tego problemu po tym, jak poruszę problem, o którym kilka osób wspomniało w jego komentarzach. Zajmuje się głównie tylko częściowym zestawem kontrolerów nazwanych plikami JavaScript.

Więc zbudowałem Helper aplikacji, aby wykryć, czy plik istnieje w katalogu javascript niezależnie od .kawa/rozszerzenie 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

Ta metoda zwróci pełną ścieżkę do pliku javascript, jeśli istnieje. W przeciwnym razie zwraca zero. Tak więc po komentarzu Pencilcheck możesz dodać tę metodę dla warunkowego include:

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

I teraz masz odpowiednie warunkowe include. A teraz kwestia prekompilowanych aktywów. Ogólnie do optymalizacji nie chcesz wstępnie skompilować aktywów indywidualnie Możesz to jednak zrobić, jeśli musi:

# Live Compilation
config.assets.compile = true

Możesz dodać do swojego pliku konfiguracyjnego środowiska. Najpierw przetestuj go w swoim pliku środowiska programistycznego. Znowu jest to niewłaściwe. Rails asset pipeline wykorzystuje koła zębate do optymalizacji wszystkiego:

Koła łańcuchowe ładują określone pliki, przetwarzają je w razie potrzeby, łączy je w jeden plik, a następnie kompresuje (jeśli Szyny.podanie.config.aktywa.compress jest prawdą). Serwując jeden plik zamiast wielu, Czas ładowania stron można znacznie zmniejszyć ponieważ przeglądarka wysyła mniej żądań. Kompresja zmniejsza również Rozmiar pliku, umożliwiając szybsze pobieranie przez przeglądarkę.

Więcej informacji na temat mechaniki kół zębatych (Asset Pipeline) można znaleźć w dokumentacji http://guides.rubyonrails.org/asset_pipeline.html

Aktywa nie są wstępnie skompilowane indywidualnie. Na przykład gdy próbuję:

<%= javascript_include_tag 'event' %>

Dostaję:

Sprockets::Rails::Helper::AssetFilteredError: Asset filtered out and nie będzie obsługiwany: dodaj Rails.application.config.assets.precompile += %w( event.js ) do config/initializers/assets.rb i uruchom ponownie swój Serwer

Możesz więc dodać, które zasoby mają być wstępnie skompilowane indywidualnie. Musimy tylko dodać odpowiedni kontroler o nazwie pliki javascript w naszym asset initializer. Możemy to zrobić programowo.

Aby uzyskać listę nazw kontrolerów użyję ecoologic ' s example :

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

A teraz, aby uzyskać nazwę wszystkie pliki javascript, które pasują do nazwy bazowej kontrolera, można użyć następującego:

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

Wtedy możesz spróbować:

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

To wyświetli listę wszystkich plików javascript, bez ścieżki katalogu, które pasują do nazwy kontrolera. Uwaga Jeśli nazwa kontrolera jest liczbą mnogą, powinna być również nazwa javascript. Zauważ również, że jeśli kontroler jest liczby pojedynczej, a plik javascript jest liczby mnogiej, to nadal będzie go zawierał, ponieważ the_file[a_controller] uda się na częściowym mecz.

Możesz wypróbować to w swoim ustawieniu Rails.application.config.assets.precompile. Wiem, że to daje Ci listę plików poprawnie. Ale zostawię cię, żebyś to przetestował. Daj mi znać, jeśli są jakieś niuanse związane z prekompilacją w ten sposób, ponieważ jestem ciekaw.

Dla bardzo dokładnego wyjaśnienia, jak aktywa precompile zobaczyć ten blog: http://www.sitepoint.com/asset-precompile-works-part/

 3
Author: 6ft Dan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:18

Niedawno znalazłem proste podejście do korzystania z generowanych skryptów dla określonego kontrolera. Używam do tego rozwiązania gem gon . Dodaj kontroler:

class HomesController < ApplicationController
  before_filter :remember_controller

  private

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

Następnie otwórz homes.js.cofee i dodaj na początku pliku:

jQuery ->
  if gon.controller == "sermons"
    # Place all functions here...
To wszystko.
 1
Author: ExiRe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-12 09:16:23