在 Rails 视图中使用通过轮询检索的数据

Posted

技术标签:

【中文标题】在 Rails 视图中使用通过轮询检索的数据【英文标题】:Using data retrieved via polling in Rails view 【发布时间】:2020-02-06 08:37:00 【问题描述】:

为了理解 javascript 短轮询,我正在尝试创建一个包含 cmets 列表的简单页面。 Rails 视图将轮询服务器以获取任何更新(新 cmets),并相应地更新页面。

到目前为止,我已经设法使用setTimeout 每 3 秒将请求发送到服务器(我可以看到,因为我每 3 秒收到一个警报)。

但是我如何将此信息反馈给视图,或者更具体地说,如何将呈现的 @comments 替换为我在响应中返回的新 cmets 列表?

<!-- index.html.erb -->
<h1>List of comments</h1>

<div id="comments">
  <%= render @comments %>
</div>

<script>
function reloadComments() 
  $.get('/', function(data, status) 
    alert("Data: " + data.comments + "\nStatus: " + status);
  );
  setTimeout(reloadComments, 3000);


// Trigger after loading the page
$(function() 
  setTimeout(reloadComments, 3000);
);
</script>
<!--_comment.html.erb-->
<div class="comment">
  <p><%= comment.content %></p>
</div>

使用 HTTP GET 调用调用的控制器方法将所有 cmets 作为 JSON 返回,如下所示:

def show
  @comments = Comment.all

  respond_to do |format|
    format.json  render json:  comments: @comments  
    format.html
  end
end

我想我的问题和这个类似,但从来没有得到满意的回答:Implementing polling for Rails Frontend to call update

另外,我知道轮询可能不是近乎实时更新的最佳解决方案(我知道 websockets)。由于此应用仅用于 POC,因此我不担心向服务器发出过多请求。

谢谢!

Ruby 版本:2.6.3 Rails 版本:6.0.0

【问题讨论】:

【参考方案1】:

您的问题有两种解决方案:

1.从您的服务器渲染js.erb 模板

js.erb 文件包含我们将从服务器发送并在前端执行的 JavaScript 代码。

简单地说,服务器不会呈现经典的 HTML,而是将您在 js.erb 文件中编写的 javascript 代码发回。这种方法的优点是您可以在模板中使用 ruby​​ 并渲染 cmets html,而不是从头开始构建它。 (有关详细信息,请参阅下面的 rails 文档链接)

在您的控制器中:

def show
  @comments = Comment.all

  respond_to do |format|
    format.js
    format.html
  end
end

在您的views/comments/show.js.erb 文件中(将由服务器呈现):

$("#comments").html('<%= j render @comments %>')

在你看来view/comments/show.html.erb

function reloadComments() 
  $.ajax(
    type: 'GET',
    url: '/comments',
    dataType: 'script'
  )


// Trigger after loading the page
$(function() 
  setTimeout(reloadComments, 3000);
);

More info in Rails docs here

2。从前端 javascript 中的 json 数据构建 HTML 模板

我不会把代码放在这里,但是网上有很多资源,这不是解决您的问题的最简单方法。

【讨论】:

感谢您的回复,但很抱歉,我是 Ajax/erb 等的新手,不太了解您的答案。但我开始意识到尝试通过 Ajax 更新 @cmets 变量可能不是最明智的方法,我正在尝试寻找替代解决方案。 嘿,Risa,我在回答中添加了更多详细信息。基本上,您向 Rails 服务器发出数据脚本请求,它将根据 Rails 约定呈现匹配的 js.erb 文件。一旦请求结束,您在此文件中写入的内容(这里我们只是渲染 @cmets 并在视图中替换它)将在前端执行。

以上是关于在 Rails 视图中使用通过轮询检索的数据的主要内容,如果未能解决你的问题,请参考以下文章

通过 REST API 检索结果并将其显示在新活动的列表视图中(列表视图出现小问题)

在 ruby​​ on rails 中无法从表单参数中检索数据

通过邮递员通过 API 使用 Rails 主动存储上传文件(.pdf、.jpg 等)? (不通过 Rails 视图)

如何使用 Rails 4 轮询数据库中的一个值,如果值更改,则使用 AJAX 刷新

轮询新 S3 对象的最佳方法?

Rails 通过 ajax 提交表单并更新视图