在Rails3中通过AJAX请求加载页面内容的最佳实践?

时间:2011-06-02 11:57:34

标签: jquery ruby-on-rails ajax ruby-on-rails-3

假设您有一个包含两列内容的页面。无论出于何种原因,您希望通过AJAX请求在页面加载后检索其中一列的HTML内容。用户不需要采取措施来加载内容(没有链接点击或表单提交),它只是自动发生。

我可以通过在主响应

中返回一个空的占位符div来轻松完成此操作
<div id="pink-dancing-elephants"></div>

然后在页面中添加一点jQuery

$.ajax({
    url: "/elephants/dancing/pink",
    cache: false,
    success: function(html){
      $("#pink-dancing-elephants").append(html);
    }
});

并且对/ elephants / dancing / pink的响应返回相应的HTML blob。

这一切都很好,但我想知道我是否缺少一些Rails3功能,这将使这更容易。例如。我正在寻找能够在主视图中放置如下内容的能力,其余部分由“魔术”发生

<%= render :url=>"/elephants/dancing/pink", :remote => true %>

我错过了什么吗?

4 个答案:

答案 0 :(得分:10)

我正在使用@ cailinanne对Dan L的帖子中所描述的方法,它对我来说效果很好。我喜欢附加到div的数据标签的可读性。在您的HTML中,您可以准确地看到要加载到该div中的内容,如果您想将此功能添加到多个div或页面,则不必添加任何新的JS。

摘自本文:http://tech.thereq.com/post/16479390885/loading-page-content-via-ajax-in-rails-3-1

使用jQuery加载方法执行此操作的最简单方法。

$("#comments").load("/blogs/2/comments");

尴尬的部分是AJAX路径(/ blogs / 2 / comments),它根据我们正在查看的博客明显改变。如果我们完全遵循jQuery文档,我们可以在HTML主体的中间放置一个脚本标记,这样在我们的模板文件中我们可能会有类似

的内容。
# show.html.erb

<div id="comments"></div>
<script>
  $("#comments").load("<%= blog_comments_path(@blog)%>");
</script>

呸。不是混合到我的模板文件中的javascript粉丝。

该怎么做?遵循Rails UJS建议的模式,并利用新的HTML数据属性。

首先,当您要在页面中加载AJAX内容时,请在模板中执行以下操作

#show.html.erb

<div id="comments" data-load="<%= blog_comments_path(@blog. :format => :js)%>">
</div>

其次,将以下内容添加到您的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);

});

第三,设置一个匹配对blog_comments的get请求的路由(类型rake routes,以查看您的路由的命名方式)

# routes.rb

# ajax load at page load
  get "/blogs/comments" => "blogs#comments"

瞧!你的评论div将被/ blogs / 3 / comments路径返回的任何东西神奇地填充!

答案 1 :(得分:6)

我认为我最初概述的实际上是最好的方法。

首先在主视图中放置一个空的占位符div

<div id="recent_posts"></div>

然后在页面中添加一点jQuery

$.ajax({
    url: "/posts/recent",
    cache: false,
    success: function(html){
      $("#recent_posts").append(html);
    }
});

并且对/ posts / recent的响应操作返回您想要填充div的HTML blob。在AJAX请求调用的操作中,您需要使用以下内容进行渲染:layout =&gt; false以保持返回的HTML blob不包含整个框架。 E.g。

# posts_controller.rb
def recent
  @recent_posts = #whatever
  render :layout => false
end

这将在views / posts / recent.html.erb中呈现模板,然后jQuery将负责将呈现的内容插入到占位符div中。

答案 2 :(得分:1)

有一种简单的源代码方法,只需将respond_to :html, :js添加到控制器并在app / views /目录中创建* .js.erb视图。您的控制器将能够响应javascript格式,您可以在* .js.erb文件中使用ruby代码编写javascript。
看看这个:Unobtrusive javascript in Rails 3

答案 3 :(得分:0)

如果您想使用OP提出的方法,我建议将其移至单独的application.js文件并使用不引人注目的JS。我不建议将JS内联放在页面本身上。

# 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

这会自动触发ajax请求,而不必将其放在每个页面上。这是更好的做法。我不会称之为最佳,但是很轻微。