Rails 3.1 asset pipeline: как загрузить скрипты, специфичные для контроллера?

Если я создам новый контроллер в Rails 3.1, также автоматически будет добавлен файл javascript с именем контроллера. Во-первых, я думал, что этот файл javascript будет использоваться только при вызове связанного контроллера.

по умолчанию есть инструкция //= require_tree . на application.js - файл, который включает в себя каждый файл javascript на его дереве.

Как я могу загрузить только сценарий контроллера?

6 ответов


для загрузки только необходимого name_of_the_js_file.файл js:

  1. удалить //=require_tree С application.js

  2. сохраните файл js (который вы хотите загрузить при загрузке определенной страницы) в конвейере активов

  3. добавить помощника в application_helper.rb

    def javascript(*files)
      content_for(:head) { javascript_include_tag(*files) }
    end
    
  4. выход в макет:

    <%= yield(:head) %>
    
  5. добавьте это в свой вид файл:

    <% javascript 'name_of_the_js_file' %>
    

тогда все должно быть в порядке


элегантным решением для этого является требование controller_name в вашем javascript_include_tag

см.http://apidock.com/rails/ActionController/Metal/controller_name/class

<%= javascript_include_tag "application", controller_name %>

controller_name.js будет загружен и также находится в активе, поэтому вам могут потребоваться другие файлы отсюда.

пример, рендеринга автомобилей#индекс даст

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

где автомобили.js может содержать

//= require wheel
//= require tyre

наслаждайтесь !


Я всегда включаю это в свои файлы макета. Он может охватить ваш js к действию

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

ваша проблема может быть решена по-разному.

добавить активы динамически

пожалуйста, подумайте, что это не хорошее решение для производственного режима, потому что ваши особенности контроллера не будут предварительно скомпилированы!

  1. добавьте к нашему помощнику приложения следующий метод:

    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. вызовите вспомогательный метод в вашем layout-file:

    <%= include_related_asset(params[:controller].to_param + '_' + params[:action].to_param . 'js') %>
    
  3. создание конкретных активов для ваших действий контроллера. Е. Г. controller_action.js

пожалуйста, не забудьте изменить YourApp к имени вашего приложения.

использовать yield

  1. добавить <%= yield :head%> в голове макета
  2. включите свои активы из ваших представлений действий:

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

смотрите рельсы направляющие для получения дополнительной информации.


мне нравится albandiguer это. С помощью которого я обнаружил, что активы javascript/coffeescript не предварительно скомпилированы. Что вызывает всевозможные ошибки при попытке использовать javascript_path. Я поделюсь своим решением этой проблемы после того, как рассмотрю вопрос, упомянутый несколькими людьми в его комментариях. В основном речь идет только о частичном наборе контроллеров с именем JavaScript-файлов.

поэтому я построил помощник приложения, чтобы определить, существует ли файл в javascript каталог независимо от .кофе./расширение 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

этот метод вернет полный путь к файлу javascript, если он существует. В противном случае он возвращает ноль. Поэтому после комментария Pencilcheck вы можете добавить этот метод для условного включения:

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

и теперь у вас есть правильное условного включения. Теперь о выпуске предварительно скомпилированных активов. В общем для оптимизации вы не хотите, чтобы активы предкомпилированного индивидуально. Однако вы можете сделать это, если вам нужно:

# Live Compilation
config.assets.compile = true

вы можете добавить это в файл конфигурации среды. Сначала проверьте его в файле среды разработки. Опять же, это нецелесообразно. Конвейер Rails asset использует звездочки для оптимизации всего:

звездочки загружают указанные файлы, при необходимости обрабатывают их, объединяет их в один файл, а затем сжимает (если Рельсы.приложение.конфиг.активы.компресс-это правда). Служа одному файл вместо многих, время загрузки страниц может быть значительно сокращено потому что браузер делает меньше запросов. Сжатие уменьшает размер файла, что позволяет браузеру загружать их быстрее.

ЧИТАЙТЕ документацию для уточнения деталей механики звездочки (конвейер активов) http://guides.rubyonrails.org/asset_pipeline.html

активы не предварительно скомпилированы по отдельности. Например, когда я попробуйте:

<%= javascript_include_tag 'event' %>

я:

звездочки:: Rails:: Helper:: AssetFilteredError: активы отфильтрованы и не будет обслуживаться: add Rails.application.config.assets.precompile += %w( event.js ) to config/initializers/assets.rb и перезагрузить сервер

таким образом, вы можете включить, какие активы должны быть предварительно скомпилированы индивидуально. Нам просто нужно добавить соответствующий контроллер с именем javascript-файлы в наш инициализатор активов. Мы можем сделать это программно.

чтобы получить список имен контроллеров, я буду использовать пример ecoologic:

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

и теперь, чтобы получить имя всех файлов javascript, которые соответствуют базовому имени имени контроллера, вы можете использовать следующее:

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

тогда вы можете попробовать:

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

это даст вам список всех файлов javascript, без пути к каталогу, которые соответствуют вашему имени контроллера. Примечание если имя контроллера-это множественное число, имя, Javascript должен быть. Также обратите внимание, если контроллер является сингулярным и файл javascript множественное число, это все равно будет включать его из-за the_file[a_controller] преуспеет в частичном совпадении.

не стесняйтесь попробовать это в вашем Rails.application.config.assets.precompile настройка. Я знаю, что это дает вам список файлов правильно. Но я оставлю вас, чтобы проверить это. Дайте мне знать, если есть какие-либо нюансы, связанные с предварительной компиляцией таким образом, как мне любопытно.

для очень подробного объяснения того, как активы precompile увидеть этот блог: http://www.sitepoint.com/asset-precompile-works-part/


недавно я нашел простой подход к использованию сгенерированных скриптов для конкретного контроллера. Я использую для этого решение камень Гон. Добавить в контроллер:

class HomesController < ApplicationController
  before_filter :remember_controller

  private

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

после этого откройте homes.js.cofee и добавьте в начале файла:

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

вот и все.