Best practices for loading page content via AJAX request in Rails3?

后端 未结 4 477
醉酒成梦
醉酒成梦 2021-01-31 21:35

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 re

相关标签:
4条回答
  • 2021-01-31 21:42

    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

    0 讨论(0)
  • 2021-01-31 21:51

    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

    0 讨论(0)
  • 2021-01-31 21:57

    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!

    0 讨论(0)
  • 2021-01-31 21:57

    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.

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