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

前端 未结 29 1810
一生所求
一生所求 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:28

    Paloma project offers interesting approach to manage page specific javascript code.

    Usage example from their docs:

    var UsersController = Paloma.controller('Users');
    
    // Executes when Rails User#new is executed.
    UsersController.prototype.new = function(){
       alert('Hello Sexy User!' );
    };
    
    0 讨论(0)
  • 2020-11-22 11:29
    <%= javascript_include_tag params[:controller] %>
    
    0 讨论(0)
  • 2020-11-22 11:29

    Philip's answer is quite good. Here is the code to make it work:

    In application.html.erb:

    <body class="<%=params[:controller].parameterize%>">

    Assuming your controller is called Projects, that will generate:

    <body class="projects">

    Then in projects.js.coffee:

    jQuery ->
      if $('body.projects').length > 0  
         $('h1').click ->
           alert 'you clicked on an h1 in Projects'
    
    0 讨论(0)
  • 2020-11-22 11:29

    Move all your commom JS files to a sub-folder like 'app/assets/javascript/global' then in the application.js, modify the //= require_tree . line to //= require_tree ./global.

    Now you are free to put your controller-specific JS on the 'app/assets/javascript/' root and they will not be included in compiled JS, being used just when you call them via = javascript_include_tag on your controller/view.

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

    Though you have several answers here, I think your edit is probably the best bet. A design pattern that we use in our team that we got from Gitlab is the Dispatcher pattern. It does something similar to what you're talking about, however the page name is set in the body tag by rails. For example, in your layout file, just include something like (in HAML):

    %body{'data-page' => "#{controller}:#{action}" }
    

    Then only have one closure and a switch statement in your dispatcher.js.coffee file in your javascripts folder like so:

    $ ->
      new Dispatcher()
    
    class Dispatcher
      constructor: ->
        page = $('body').attr('data-page')
        switch page
          when 'products:index'
            new Products() 
          when 'users:login'
            new Login()
    

    All you need to do in the individual files (say products.js.coffee or login.js.coffee for example) is enclose them in a class and then globalize that class symbol so you can access it in the dispatcher:

    class Products
      constructor: ->
        #do stuff
    @Products = Products
    

    Gitlab has several examples of this that you might want to poke around with in case you're curious :)

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

    You can also group the js in folders and continue to use the asset pipeline to load your javascript selectively depending on the page.

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