Best practices for loading page content via AJAX request in Rails3?
Suppose you have a page with two columns of content. For whatever reason, you wish to retrieve the HTML content of one of those columns after the page has loaded, via an AJAX request. The user does not need to take an action to make the content load (no link clicking or form submissions), it just happens automatically.
I can easily do this by returning an empty placeholder div in the main response
<div id="pink-dancing-elephants"></div>
and then add a little jQuery to the page
$.ajax({
url: "/elephants/dancing/pink",
cache: false,
succe开发者_如何学编程ss: function(html){
$("#pink-dancing-elephants").append(html);
}
});
and have the action that responses to /elephants/dancing/pink return the corresponding blob of HTML.
This all works fine, but I'm wondering if I'm missing some Rails3 feature that would make this easier. E.g. I'm searching for the ability to be able to just put something like the following in the main view and have the rest of it happen by "magic"
<%= render :url=>"/elephants/dancing/pink", :remote => true %>
Am I missing something?
I am using the method described in @cailinanne's comment to Dan L's post and it's worked well for me. I like the readability of the data tag that's attached to the div. Within your html you can see exactly what's going to load into that div, and you don't have to add any new JS if you want to add this functionality to multiple divs or pages.
Taking from this article: http://tech.thereq.com/post/16479390885/loading-page-content-via-ajax-in-rails-3-1
The simplest way to do this to use the jQuery load method.
$("#comments").load("/blogs/2/comments");
The awkward part is the AJAX path (/blogs/2/comments) which clearly changes according to which blog we are viewing. If we followed the jQuery documentation exactly, we could just plop a script tag in the middle of our HTML body, so that in our template file we might have something like
# show.html.erb
<div id="comments"></div>
<script>
$("#comments").load("<%= blog_comments_path(@blog)%>");
</script>
Yuck. Not a fan of javascript mixed into my template files.
What to do instead? Follow the pattern suggested by Rails UJS and take advantage of the new HTML data- attributes.
First, when you want to load AJAX content in your page, do the following in your template
#show.html.erb
<div id="comments" data-load="<%= blog_comments_path(@blog. :format => :js)%>">
</div>
Second, add the following to your application.js
# application.js or any JS file loaded within application.js
$("div[data-load]").filter(":visible").each(function(){
var path = $(this).attr('data-load');
$(this).load(path);
});
Third, set up a route that matches a get request to blog_comments (type rake routes
to see how your routes are named)
# routes.rb
# ajax load at page load
get "/blogs/comments" => "blogs#comments"
And voila! Your comments div will magically be filled by whatever is returned by the /blogs/3/comments path!
I think what I originally outlined is actually the best approach.
First put an empty, placeholder div in your main view
<div id="recent_posts"></div>
and then add a little jQuery to the page
$.ajax({
url: "/posts/recent",
cache: false,
success: function(html){
$("#recent_posts").append(html);
}
});
and have the action that responses to /posts/recent return the blob of HTML that you want to have fill up the div. In the action that is invoked by the AJAX request, you'll want to render with :layout => false to keep the returned blob of HTML from including the entire frame. E.g.
# posts_controller.rb
def recent
@recent_posts = #whatever
render :layout => false
end
This would render the template in views/posts/recent.html.erb and then the jQuery will take care of inserting the rendered contents into your placeholder div.
There is a simple way ofcource, just add respond_to :html, :js
to your controller and create *.js.erb views in your app/views/ directory. Your controller will then be able to respond to javascript format and you can write javascript with ruby code in *.js.erb files.
Check this out: Unobtrusive javascript in Rails 3
If you want to use the approach the OP proposed, I would recommend moving it to a separate application.js file and use unobtrusive JS. I wouldn't recommend putting the JS inline on the page itself.
# index.html.erb
<div id="content"></div>
# application.js
$(function() {
$.ajax({
url: "...",
success: function (html) {
$("#content").append(html);
}
});
});
# controller.rb
# empty placeholder
def index
end
This fires off the ajax request automatically without you having to put it on every page. It's better practice. I wouldn't call it optimal, but slighty m
精彩评论