首页 文章

Rails 3.1资产管道:如何加载特定于控制器的脚本?

提问于
浏览
76

如果我在Rails 3.1中生成一个新的控制器,也会自动添加一个带有控制器名称的javascript文件 . 首先,我认为这个javascript文件只会在调用相关控制器时使用 .

默认情况下, application.js -file中有指令 //= require_tree . ,其中包含树上的每个javascript文件 .

我怎么才能加载控制器特定的脚本?

6 回答

  • 3

    要仅加载必要的name_of_the_js_file.js文件:

    • application.js 删除 //=require_tree

    • 保留资产管道中的js文件(加载特定页面时要加载的文件)

    • application_helper.rb 添加帮手

    def javascript(*files)
      content_for(:head) { javascript_include_tag(*files) }
    end
    
    • 收益你的布局:
    <%= yield(:head) %>
    
    • 在您的视图文件中添加:
    <% javascript 'name_of_the_js_file' %>
    

    那应该没问题

  • 6

    一个优雅的解决方案是在javascript_include_tag中要求controller_name

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

    <%= javascript_include_tag "application", controller_name %>
    

    controller_name.js将被加载并且也在资产中,因此您可以从此处获取其他文件 .

    例如,渲染汽车#index将给出

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

    cars.js可以包含的地方

    //= require wheel
    //= require tyre
    

    请享用 !

  • 83

    我总是在布局文件中包含这个 . 它可以将你的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
    
    • 调用 layout -file中的helper方法:
    <%= include_related_asset(params[:controller].to_param + '_' + params[:action].to_param . 'js') %>
    
    • 为控制器操作创建特定资产 . E. g . controller_action.js

    请不要忘记将 YourApp 更改为您的应用名称 .

    使用产量

    • <%= yield :head%> 添加到布局头部

    • 在操作视图中包含您的资源:

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

    有关详细信息,请参阅Rails guides .

  • 122

    我喜欢albandiguer's solution . 我发现javascript / coffeescript资产没有单独预编译 . 这会导致尝试使用 javascript_path 的各种错误 . 在我解决他的评论中提到的一些问题后,我将分享我对该问题的解决方案 . 主要处理名为JavaScript文件的部分控制器 .

    所以我构建了一个应用程序帮助器来检测文件是否存在于javascript目录中,而不管.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
    

    此方法将返回javascript文件的完整路径(如果存在) . 否则返回nil . 因此,遵循Pencilcheck的评论,您可以为条件包括添加此方法:

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

    现在你有一个适当的条件包括 . 现在讨论预编译资产 . 通常用于单独优化 you don't want assets precompiled . 但是如果你必须这样做,你可以这样做:

    # Live Compilation
    config.assets.compile = true
    

    您可以添加此环境配置文件 . 首先在开发环境文件中测试它 . 再次这是不合理的 . Rails资产管道使用Sprockets来优化所有内容:

    Sprockets加载指定的文件,必要时处理它们,将它们连接成一个文件,然后压缩它们(如果Rails.application.config.assets.compress为true) . 通过提供一个文件而不是多个文件,可以大大减少页面的加载时间,因为浏览器会减少请求 . 压缩还可以减小文件大小,使浏览器能够更快地下载它们 .

    PLEASE READ 有关Sprockets (Asset Pipeline) http://guides.rubyonrails.org/asset_pipeline.html力学更多细节的文件

    资产不是单独预编译的 . 例如,当我尝试:

    <%= javascript_include_tag 'event' %>
    

    我明白了:

    Sprockets :: Rails :: Helper :: AssetFilteredError:资产被过滤掉并且不会被提供:将Rails.application.config.assets.precompile =%w(event.js)添加到config / initializers / assets.rb并重新启动服务器

    因此,您可以包含要单独预编译的资产 . 我们只需要在资产初始化程序中添加名为javascript文件的相关控制器 . 好吧,我们可以以编程方式执行此操作 .

    要获取控制器名称列表,我将使用ecoologic's example

    all_controllers =  Dir[
        Rails.root.join('app/controllers/*_controller.rb')
      ].map { |path|
        path.match(/(\w+)_controller.rb/); $1
      }.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/

  • 28

    我最近发现了一种为特定控制器使用生成脚本的简单方法 . 我用于那个解决方案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...
    

    就这些 .

相关问题