Using Rails 3.1, where do you put your “page speci

2018-12-31 14:27发布

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 application.js manifest file.

This sounds like a real life-saver, but I am a little concerned about page-specific JavaScript code. Does this code get executed on every page? The last thing I want is for all of my objects to be instantiated for every page when they are only needed on 1 page.

Also, isn't there potential for code that clashes too?

Or do you put a small script tag at the bottom of the page that just calls into a method that executes the javascript code for the page?

Do you no longer need require.js then?

Thanks

EDIT: 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, 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.

I think this is the actual answer to my question.

29条回答
笑指拈花
2楼-- · 2018-12-31 15:20

Maybe you will find pluggable_js gem as suitable solution.

查看更多
ら面具成の殇う
3楼-- · 2018-12-31 15:23

The LoadJS gem is another option:

LoadJS provides a way to load page-specific Javascript code in a Rails app without loosing the magic provided by Sprockets. All your Javascript code will continue by minified in one Javascript file but some portions of it will only be executed for certain pages.

https://github.com/guidomb/loadjs

查看更多
不再属于我。
4楼-- · 2018-12-31 15:23

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!' );
};
查看更多
君临天下
5楼-- · 2018-12-31 15:23

I haven't tried this out, but it looks like the following is true:

  • if you have a content_for that is javascript (e.g. with real javascript within it), sprockets would not know about it and thus this would work the same way as it does now.

  • if you want to exclude a file from the big bundle of javascript, you would go into config/sprockets.yml file and modify the source_files accordingly. Then, you would just include any of the files that you excluded where needed.

查看更多
姐姐魅力值爆表
6楼-- · 2018-12-31 15:24

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'
查看更多
弹指情弦暗扣
7楼-- · 2018-12-31 15:24

Here's how to do it especially if you don't have to execute tons of libraries for your specific page, but only to run a few hundreds lines of JS more or less.

Since it's perfectly fine to embed Javascript code into HTML, just create under app/views shared.js directory and place there your page/pages specific code inside my_cool_partial.html.erb

<script type="text/javascript"> 
<!--
  var your_code_goes_here = 0;
  function etc() {
     ...
  }
-->
</script>

So now from wherever you want you simply do:

  = render :partial => 'shared.js/my_cool_partial'

And that's it, k?

查看更多
登录 后发表回答