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

Using data retrieved via polling in Rails view

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

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

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

<!-- 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 调用调用的控制器方法 returns 所有注释作为 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.从您的服务器渲染 js.erb 模板

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

简单地说,服务器不会呈现经典 HTML,而是发回您在 js.erb 文件中编写的 javascript 代码。这种方法的优点是您可以在模板中使用 ruby 并呈现您的评论 html 而不是从头开始构建它。 (有关详细信息,请参阅下面的 link 到 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。从前端的 json 数据构建 HTML 模板 javascript

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