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

时间:2021-12-04 02:04:51

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.

假设您有一个包含两列内容的页面。不管出于什么原因,您希望通过AJAX请求在页面加载后检索其中一列的HTML内容。用户不需要采取任何操作来加载内容(不需要点击链接或提交表单),它会自动执行。

I can easily do this by returning an empty placeholder div in the main response

我可以通过在主响应中返回空占位符div来轻松实现这一点。

<div id="pink-dancing-elephants"></div>

and then add a little jQuery to the page

然后在页面中添加一点jQuery

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

and have the action that responses to /elephants/dancing/pink return the corresponding blob of HTML.

并让响应/elephant /dancing/pink的动作返回相应的HTML blob。

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"

这些都可以正常工作,但是我想知道我是否遗漏了一些Rails3特性,以便更容易地完成这项工作。我正在寻找一种能力,能够将如下内容放到主视图中,并通过“magic”实现其余内容

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

Am I missing something?

我遗漏了什么东西?

4 个解决方案

#1


10  

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.

我正在使用@cailinanne对Dan L文章的评论中描述的方法,它对我很有效。我喜欢div的数据标签的可读性。在html中,你可以看到要加载到div中的内容,如果你想在多个div或页面中添加这个功能,你不需要添加任何新的JS。

Taking from this article: http://tech.thereq.com/post/16479390885/loading-page-content-via-ajax-in-rails-3-1

本文摘录:http://tech.thereq.com/post/1647939088.5 / loadingpage -content-via- ajaxin - rails3 -1

The simplest way to do this to use the jQuery load method.

最简单的方法是使用jQuery加载方法。

$("#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

令人尴尬的部分是AJAX路径(/blogs/2/comments),它显然根据我们正在查看的博客而变化。如果我们严格遵循jQuery文档,我们可以在HTML主体的中间插入一个脚本标记,这样在我们的模板文件中我们可能会有类似的东西

# 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.

讨厌的东西。我不喜欢javascript混合到我的模板文件中。

What to do instead? Follow the pattern suggested by Rails UJS and take advantage of the new HTML data- attributes.

要做什么呢?遵循Rails UJS建议的模式,利用新的HTML数据属性。

First, when you want to load AJAX content in your page, do the following in your template

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

#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中

# 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)

第三,设置一条路由,匹配到blog_comments的get请求(键入rake路由,查看路由的名称)

# 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!

瞧!你的评论div会神奇地被/blogs/3/comments路径返回的内容所填充!

#2


6  

I think what I originally outlined is actually the best approach.

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

First put an empty, placeholder div in your main view

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

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

and then add a little jQuery to the page

然后在页面中添加一点jQuery

$.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.

和反应的行动/文章/最近返回HTML的blob,你想填满了div。由AJAX请求调用的动作,你要渲染:布局= >假防止blob的HTML返回包括整个框架。如。

# 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.

这将在视图/posts/最近.html中呈现模板。erb和jQuery将负责将呈现的内容插入到占位符div中。

#3


1  

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

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

#4


0  

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.

如果您想使用OP建议的方法,我建议将其移到一个单独的应用程序。使用不显眼的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

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

这将自动触发ajax请求,而不需要将其放在每个页面上。这是更好的做法。我不认为它是最优的,但稍微有点

#1


10  

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.

我正在使用@cailinanne对Dan L文章的评论中描述的方法,它对我很有效。我喜欢div的数据标签的可读性。在html中,你可以看到要加载到div中的内容,如果你想在多个div或页面中添加这个功能,你不需要添加任何新的JS。

Taking from this article: http://tech.thereq.com/post/16479390885/loading-page-content-via-ajax-in-rails-3-1

本文摘录:http://tech.thereq.com/post/1647939088.5 / loadingpage -content-via- ajaxin - rails3 -1

The simplest way to do this to use the jQuery load method.

最简单的方法是使用jQuery加载方法。

$("#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

令人尴尬的部分是AJAX路径(/blogs/2/comments),它显然根据我们正在查看的博客而变化。如果我们严格遵循jQuery文档,我们可以在HTML主体的中间插入一个脚本标记,这样在我们的模板文件中我们可能会有类似的东西

# 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.

讨厌的东西。我不喜欢javascript混合到我的模板文件中。

What to do instead? Follow the pattern suggested by Rails UJS and take advantage of the new HTML data- attributes.

要做什么呢?遵循Rails UJS建议的模式,利用新的HTML数据属性。

First, when you want to load AJAX content in your page, do the following in your template

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

#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中

# 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)

第三,设置一条路由,匹配到blog_comments的get请求(键入rake路由,查看路由的名称)

# 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!

瞧!你的评论div会神奇地被/blogs/3/comments路径返回的内容所填充!

#2


6  

I think what I originally outlined is actually the best approach.

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

First put an empty, placeholder div in your main view

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

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

and then add a little jQuery to the page

然后在页面中添加一点jQuery

$.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.

和反应的行动/文章/最近返回HTML的blob,你想填满了div。由AJAX请求调用的动作,你要渲染:布局= >假防止blob的HTML返回包括整个框架。如。

# 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.

这将在视图/posts/最近.html中呈现模板。erb和jQuery将负责将呈现的内容插入到占位符div中。

#3


1  

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

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

#4


0  

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.

如果您想使用OP建议的方法,我建议将其移到一个单独的应用程序。使用不显眼的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

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

这将自动触发ajax请求,而不需要将其放在每个页面上。这是更好的做法。我不认为它是最优的,但稍微有点