Rails 3.1 asset pipeline: как загрузить скрипты, специфичные для контроллера?
Если я создам новый контроллер в Rails 3.1, также будет автоматически добавлен файл javascript с именем контроллера. Во-первых, я думал, что этот файл javascript будет использоваться только при вызове соответствующего контроллера.
по умолчанию есть инструкция //= require_tree .
на application.js
- файл, который включает в себя каждый файл javascript на его дереве.
Как я могу загрузить только конкретный скрипт контроллера?
6 ответов:
чтобы загрузить только нужный name_of_the_js_file.js file:
удалить
//=require_tree
Сapplication.js
храните свой js-файл (который вы хотите загрузить при загрузке определенной страницы) в конвейере активов
добавить помощника в
application_helper.rb
def javascript(*files) content_for(:head) { javascript_include_tag(*files) } end
выход в макет:
<%= yield(:head) %>
добавить это в вашем представлении файл:
<% 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") %>
ваша проблема может быть решена по-разному.
добавить активы динамически
пожалуйста, учтите, что это не очень хорошее решение для производственного режима, потому что ваши особенности контроллера не будут предварительно скомпилированы!
добавьте к нашему помощнику приложения следующий метод:
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
вызовите вспомогательный метод в вашем
layout
- file:<%= include_related_asset(params[:controller].to_param + '_' + params[:action].to_param . 'js') %>
создание конкретных активов для ваших действий контроллера. Е. Г.
controller_action.js
пожалуйста, не забудьте изменить
YourApp
к имени вашего приложения.использовать
yield
- добавить
<%= yield :head%>
в голове макетавключите свои активы из ваших представлений действий:
<% 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, если он существует. В противном случае он возвращает nil. Поэтому после комментария Pencilcheck вы можете добавить этот метод для условного включения:
<%= javascript_include_tag(controller_name) if javascript_asset_path(controller_name) %>
и теперь у вас есть правильное условного включения. Теперь о выпуске предварительно скомпилированных активов. В общем для оптимизации вы не хотите предварительно скомпилировать активы индивидуально. Однако вы можете сделать это, если вы должны:
# Live Compilation config.assets.compile = true
вы можете добавить это сделать файл конфигурации среды. Сначала проверьте его в файле среды разработки. Опять же, это нецелесообразно. Конвейер Rails asset использует звездочки для оптимизации всего:
Sprockets загружает указанные файлы, обрабатывает их при необходимости, объединяет их в один файл, а затем сжимает (если Рельсы.приложение.конфиг.активы.компресс-это правда). Путем служения одного файл вместо многих, время загрузки страниц может быть значительно сокращено потому что браузер делает меньше запросов. Сжатие также уменьшает размер файла, что позволяет браузеру загружать их быстрее.
ПОЖАЛУЙСТА, ПРОЧИТАЙТЕ документация для более подробной информации о механике звездочки (трубопровод активов) http://guides.rubyonrails.org/asset_pipeline.html
активы не предварительно скомпилированы по отдельности. Например, когда я попробуйте:
<%= javascript_include_tag 'event' %>
я:
звездочки:: рельсы:: помощник:: AssetFilteredError: актив отфильтрован и не будет подаваться: добавить
Rails.application.config.assets.precompile += %w( event.js )
доconfig/initializers/assets.rb
и перезагрузить сервертаким образом, вы можете включить, какие активы должны быть предварительно скомпилированы по отдельности. Нам просто нужно добавить соответствующий контроллер с именем javascript файлы в нашем инициализаторе активов. Ну мы можем сделать это программно.
чтобы получить список имен контроллеров я буду используйте пример эколого:
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
настройка. Я знаю, что это дает вам список файлов правильно. Но я оставлю вас, чтобы проверить это. Дайте мне знать, если есть какие-либо нюансы, связанные с предварительной компиляцией таким образом, как мне любопытно.для очень подробного объяснения о том, как предварительно скомпилировать активы см. Этот блог: http://www.sitepoint.com/asset-precompile-works-part/
недавно я нашел простой подход к использованию сгенерированных скриптов для конкретного контроллера. Я использую для этого решения gem gon. Добавьте в контроллер:
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...
вот и все.