实现轮询Rails前端调用更新

Implementing polling for Rails Frontend to call update

本文关键字:调用 更新 前端 Rails 实现      更新时间:2023-09-26

我想实现一个系统,其中我的'show'视图,每10秒将调用控制器中的update,然后异步更新视图而不刷新页面。

我把它放在异步更新的地方。但是我需要让它轮询。

我的方法是:

  • controller show action响应JS

    def show
        @simulation = Simulation.find(params[:id])
    end
    
  • JS会做这样的事情。

// starts the polling on page load
$(function() {
    setTimeout(callUpdate, 10000);
});
// Continues to poll, making ajax calls 
function callUpdate() {
    if ($(this).hasClass("update")) {
      $.ajax({
        type: "PUT",
        url: "/simulations/<%= @simulation.id %>"
      });
    } else {
      alert("An error occured updating record.");
    }
    $('#sim_div').html("<%= j (render @simulation) %>");
    setTimeout(callUpdate, 10000);
}

正确的做法是什么?我试过在资产中使用coffeescript,但它在每个控制器元素上都被调用,我试过将它嵌入html中或试图将其作为部分包含,但我要么得到渲染ruby代码的问题,我也需要,或者没有获得足够的访问权限,我试过做respond_to,但它只给我html。有人能帮我解决这个问题吗?

编辑:

这是我的show视图:

<%= render 'simulation' %>
<%= link_to 'Back', simulations_path %>

和包含的部分:

<div id="sim_div">
  <h1><%= @simulation.identifier %></h1>
  <h4 class="offset-col-sm-1">Dimensions: <%= @simulation.x_size %>x<%= @simulation.y_size %></h4>
  <h4 class="offset-col-sm-1">Verdict: <%= @simulation.verdict %></h4>
  <table class="table table-bordered">
    <thead>
      <tr>
      </tr>
    </thead>
    <tbody>
      <% @simulation.state.each do |row| %>
        <tr>
        <% row.each do |current| %>        
            <td class="text-center"><%= current %></td>        
          <% end%>
        </tr>
      <% end %>
    </tbody>
  </table>
  <br>
</div>

我的解决方案是:

$.ajax({ method: "PUT", url: $(".some-element").data("url") })
.done(function(data) {
  //here you can use the new data
});

变化是你有一个类为"some-element"的元素,它的属性data-url被设置为rails自动为更新路由生成的路径。在你的html中,你将有:

<div class='some-element' data-url="<%= simulations_path(@simulation) %>">
  ...
</div>

在你的控制器中,你应该返回@simulation作为json。

这个解决方案的另一个优点是,你可以避免在javascript中嵌入ruby,这意味着服务器为每个请求发送文件。

轮询是正确的,但是其他的方法是使用web套接字。在Rails中,你有一些宝石可以做到这一点,在不久的将来,Rails 5将与ActionCable一起推出。无论如何,我会继续使用轮询,因为它比websockets简单得多。

这个解决方案的工作方式:

  1. 你请求显示视图,服务器用html, js和css文件响应。
  2. 轮询开始,每10秒一个请求被发送到模拟#更新(模拟控制器/更新动作)。在那里你可以更新和保存你的模拟,并返回新的值。
  3. jquery的ajax。当你得到新的数据,你可以更新客户端数据。

希望有帮助,

圣地亚哥