Using Rails 3.1, where do you put your “page specific” JavaScript code?

前端 未结 29 1812
一生所求
一生所求 2020-11-22 11:08

To my understanding, all of your JavaScript gets merged into 1 file. Rails does this by default when it adds //= require_tree . to the bottom of your appl

相关标签:
29条回答
  • 2020-11-22 11:38

    The Asset Pipeline docs suggest how to do controller-specific JS:

    For example, if a ProjectsController is generated, there will be a new file at app/assets/javascripts/projects.js.coffee and another at app/assets/stylesheets/projects.css.scss. You should put any JavaScript or CSS unique to a controller inside their respective asset files, as these files can then be loaded just for these controllers with lines such as <%= javascript_include_tag params[:controller] %> or <%= stylesheet_link_tag params[:controller] %>.

    Link to: asset_pipeline

    0 讨论(0)
  • 2020-11-22 11:39

    I see that you've answered your own question, but here's another option:

    Basically, you're making the assumption that

    //= require_tree .
    

    is required. It's not. Feel free to remove it. In my current application, the first I'm doing with 3.1.x honestly, I've made three different top level JS files. My application.js file only has

    //= require jquery
    //= require jquery_ujs
    //= require_directory .
    //= require_directory ./api
    //= require_directory ./admin
    

    This way, I can create subdirectories, with their own top level JS files, that only include what I need.

    The keys are:

    1. You can remove require_tree - Rails lets you change the assumptions it makes
    2. There's nothing special about the name application.js - any file in the assets/javascript subdirectory can include pre-processor directives with //=

    Hope that helps and adds some details to ClosureCowboy's answer.

    Sujal

    0 讨论(0)
  • 2020-11-22 11:39

    Step1. remove require_tree . in your application.js and application.css.

    Step2. Edit your application.html.erb(by rails default) in layout folder. Add "params[:controller]" in the following tags.

    <%= stylesheet_link_tag    'application', params[:controller], media: 'all', 'data-turbolinks-track' => true %>
    
    <%= javascript_include_tag 'application', params[:controller], 'data-turbolinks-track' => true %>
    

    Step3. Add a file in config/initializers/assets.rb

    %w( controller_one controller_two controller_three ).each do |controller|
      Rails.application.config.assets.precompile += ["#{controller}.js", "#{controller}.js.coffee", "#{controller}.css", "#{controller}.scss"]
    end
    

    references: http://theflyingdeveloper.com/controller-specific-assets-with-rails-4/

    0 讨论(0)
  • 2020-11-22 11:40

    I appreciate all the answers... and I don't think they are really getting at the problem. Some of them are about styling and don't seem to relate... and others just mention javascript_include_tag... which I know exists (obviously...) but it would appear that the Rails 3.1 way going forward is to wrap up all of your Javascript into 1 file rather than loading individual Javascript at the bottom of each page.

    The best solution I can come up with is to wrap certain features in div tags with ids or classes. In the javascript code. Then you just check if the id or class is on the page, and if it is, you run the javascript code that is associated with it. This way if the dynamic element is not on the page, the javascript code doesn't run - even though it's been included in the massive application.js file packaged by Sprockets.

    My above solution has the benefit that if a search box is included on 8 of the 100 pages, it will run on only those 8 pages. You also won't have to include the same code on 8 of the pages on the site. In fact, you'll never have to include manual script tags on your site anywhere ever again - except to maybe preload data.

    I think this is the actual answer to my question.

    0 讨论(0)
  • 2020-11-22 11:45

    I have another solution, which although primitive works fine for me and doesn't need any fancy selective loading strategies. Put in your nornal document ready function, but then test the current windows location to see if it is the page your javascript is intended for:

    $(document).ready(function() {
       if(window.location.pathname.indexOf('/yourpage') != -1) {
              // the javascript you want to execute
       }
    }
    

    This still allows all the js to be loaded by rails 3.x in one small package, but does not generate much overhead or any conflicts with pages for which the js isn't intended.

    0 讨论(0)
提交回复
热议问题