Rails 3.1 Asset Pipeline for Javascript - Stack Overflow

Ok, I've read a lot of information about the new Asset Pipeline for Rails 3.1 and I couldn't

Ok, I've read a lot of information about the new Asset Pipeline for Rails 3.1 and I couldn't find a proper answer to my doubt.

I was loading my .js files according to the view#action I was rendering, on demand. I was doing this to prevent incorrect bindings and to load small .js files.

candidate_opportunities#index

$(".sortable_drag_n_drop").sortable({
    update: function(event, ui) {
        $.post('/candidate_opportunities/sort', $(this).sortable('serialize'));
    },
    handle: 'span'
});

candidate_panies#index

$(".sortable_drag_n_drop").sortable({
    update: function(event, ui) {
        $.post('/candidate_panies/sort', $(this).sortable('serialize'));
    },
    handle: 'span'
});
$(".sortable_drag_n_drop").disableSelection();

What is the best solution now?

  • Should I change my bindings and let Sprockets pile all my .js files using //= require_tree . ?
  • Or should I try to load my .js according to my views, so I don't end up with a huge application.js?

Ok, I've read a lot of information about the new Asset Pipeline for Rails 3.1 and I couldn't find a proper answer to my doubt.

I was loading my .js files according to the view#action I was rendering, on demand. I was doing this to prevent incorrect bindings and to load small .js files.

candidate_opportunities#index

$(".sortable_drag_n_drop").sortable({
    update: function(event, ui) {
        $.post('/candidate_opportunities/sort', $(this).sortable('serialize'));
    },
    handle: 'span'
});

candidate_panies#index

$(".sortable_drag_n_drop").sortable({
    update: function(event, ui) {
        $.post('/candidate_panies/sort', $(this).sortable('serialize'));
    },
    handle: 'span'
});
$(".sortable_drag_n_drop").disableSelection();

What is the best solution now?

  • Should I change my bindings and let Sprockets pile all my .js files using //= require_tree . ?
  • Or should I try to load my .js according to my views, so I don't end up with a huge application.js?
Share Improve this question asked Sep 15, 2011 at 22:37 Rafael OliveiraRafael Oliveira 2,9234 gold badges35 silver badges50 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

If you are updating this to the pipeline you have several options. You should probably take the way the pipeline should work into account in deciding.

Broadly speaking, the aim of he pipeline is to join all your JS into one file and minfy/press it. The point in doing this is reduce the number of requests per page, and to allow far-future headers to be set so that the resource is cached at the browser or somewhere in a transparent proxy/cache.

On to the options.

1. The same as you do now.

You could keep doing the same thing as you do know. I presume that you are using the rails helpers to add these view JS files in the main layout file. You could keep doing the same with the pipeline, however you must add all the files you use to the prepile array:

config.assets.prepile += ['candidate_opportunities.js', 'candidate_panies']

The assets must be in assets/javascripts but there is no need to add them to the manifest file as you are adding each on individually.

It is highly remended that you stick with the Rails defaults for the pipeline and prepile assets for production.

The downside is an extra request on those pages, but this is only an issue if the app is under high load.

2. The Asset Pipeline Way (TM)

To do this with the pipeline you would need to move these files into assets/javascripts and require_tree as you say.

The issue in your case is that the JS snippets target the same class (but with a different post URLs), so this is not going to work. And with require_tree the order of the files might not be what you want.

A new 3.1 app generates files for views (I think), but the expectation is that they will target unique attributes (from a site perspective) in the markup, because all the files get included in the application.js

To get around the problem of JS clashes. I would suggest that you refactor the JS snippet so that it is more generic. You could use a data-post-url attribute on the sortable object:

<ul class="sortable_drag_n_drop" data-post-url="/candidate_opportunities/sort">

and then collect the url in your JS.

Not only is that DRYer, but you have less overall JS and can fully use the pipeline as intended.

I'm frustrated on Rails asset pipeline. Maybe not the whole asset pipeline thing but the way Rails organize javascript is really not logical.

As of now, Rails has a separate javascript file per controller. Which is somewhat good in terms of logical organization. But then the asset pipeline presses all those files into one big js file. So basically your js files are well organized but then they are loaded all at once, resulting to variable clashes, function clashes, other code clashes and other unexpected behavior. Because what we really want as developers is a simple way to execute or load a page specific javascript.

One famous approach is to just include a specific javascript file per page. Yes, that will work, but we are not using the performance boost given by the asset pipeline if we are requesting different javascript files per page.

My solution is to create an javascript object that holds all the page-specific functions then fetch and execute them once the matching controller-action pair is executed by Rails. Something like this:

PageJs = {};
PageJs["users/new"] = function(){ 
  alert("I will be called when users/new action is executed");
};

Basically, that's the core idea. Well I've implemented that idea and created a gem for it. Checkout Paloma, and see how you can logically organize your js files and execute page-specific javascript without plex setups.

Here's an example on how Paloma is used:

Javascript file:

Paloma.callbacks['users/new'] = function(params){
  // This will only run after executing users/new action
  alert('Hello New Sexy User');
};

Rails controller:

def UsersController < ApplicationController
  def new
    @user = User.new
    # No special function to call, 
    # the javascript callback will be executed automatically
  end
end

That's just a quick example, but it has lot more to offer, and I'm sure it can solve your problem. Easily.

Thank You!

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745644842a4637906.html

相关推荐

  • Rails 3.1 Asset Pipeline for Javascript - Stack Overflow

    Ok, I've read a lot of information about the new Asset Pipeline for Rails 3.1 and I couldn't

    5小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信