如何在rails中异步加载部分页面

Posted

技术标签:

【中文标题】如何在rails中异步加载部分页面【英文标题】:How to asynchronously load a partial page in rails 【发布时间】:2011-10-05 19:24:45 【问题描述】:

在创建 ruby​​ on rails / jquery 应用程序时,生成页面的一部分非常耗时。

我想改变页面的加载方式,使大部分页面立即加载,并为耗时的部分保留一个占位符以异步加载,并在加载时使用ajax / jquery注入页面完成了。

我现在拥有的(简化):

app/views/sample/show.html.erb:

<div id="theResult">
    <%= render :partial => 'calculate', :object => @org) %>
</div>

partial 将使用 @org 的某些部分来生成一些内容(访问另一个外部 REST 服务)。

app/views/sample/_calculate.html.erb

<%
    # code to take org and turn it into content
%>
<!--...html to display results here -->

我意识到这可能违反了正确的 MVC 架构规则,因为我的部分似乎有太多逻辑,并且也想清理它......

所以我想我有两个问题合二为一:(1) 我如何让它工作,以及 (2) 我应该如何清理它以遵循良好的 ruby​​/rails/mvc 实践?

【问题讨论】:

Watch here, maybe it helps you 【参考方案1】:

首先在主响应中放置一个空的占位符 div

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

然后在页面中添加一点 jQuery

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

并让响应 /elephants/dancing/pink 的操作返回您希望填充 div 的 HTML 块。在由 AJAX 请求调用的操作中,您需要使用 :layout => false 进行渲染,以防止返回的 HTML blob 包含整个帧。例如

# elephants_controller.rb
def dancing
  @elephants = #whatever
  render :layout => false
end

这将在views/elephants/dancing.html.erb 中呈现模板。

【讨论】:

谢谢 - 这行得通,绝对可以让我得到我正在寻找的结果。你知道是否有一种方法可以做到这一点而不必在路线中放置“/elephants/dancing”(允许某人独立于主页查看它) 听起来你几乎可以使用路由约束来做到这一点(参见Section 3.9,但根据文档,你只能使用返回字符串的请求方法。在你的情况下,你会想要使用 request.xhr? 方法,该方法返回一个布尔值。 我想指出this 对于像我这样尝试使用上面显示的内容加载集合的人的答案。感谢您的帮助!【参考方案2】:

与@cailinanne 相比,有一种更简单的方法。

使用她的相同示例,但我倾向于使用这种技术来更新 div,因此我的 div 将首先具有该部分:

<div id="pink-dancing-elephants">
   <%= render "elephants/dancing", elephant: some_thing  %>
</div>

但是然后使用jQuery加载方法:

$("#pink-dancing-elephants").load("/elephants/dancing");

这将返回整个部分。请务必使用 layout: false,并可选择设置参数。我倾向于使用这样的部分

# elephants_controller.rb
def dancing
  render "elephants/_dancing", 
         locals:  elephant: some_thing ,
         layout: false
end

这将在 views/elephants/_dancing.html.erb 中呈现模板。

注意控制器方法的部分名称中的下划线,以及在视图中调用渲染时如何不使用它。

【讨论】:

您能解释一下为什么在模板和控制器中都需要调用render ... @jberger:他正在解释如何使用公认答案的技术来刷新已经加载的部分。模板的render 用于第一次加载;控制器用于后续的异步更新。

以上是关于如何在rails中异步加载部分页面的主要内容,如果未能解决你的问题,请参考以下文章

关于爬取异步加载的页面

Django:请求页面时异步加载数据?

如何异步加载和显示数据

如何延迟或异步此 WordPress javascript 片段以最后加载以加快页面加载时间?

当片段视图加载是异步任务的一部分时,如何在片段加载之前显示进度条?

JS异步函数停止页面加载