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


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

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

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

6 76

6 ответов:

чтобы загрузить только нужный name_of_the_js_file.js file:

  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, если он существует. В противном случае он возвращает 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...

вот и все.