Implementing polling for Rails Frontend to call update

人走茶凉 提交于 2019-12-11 12:56:41

问题


I want to implement a system where my 'show' view, every 10 seconds will call update in the controller, then asynchronously updates the view without refreshing the page.

I have it at the point where it updates asynchronously. However I need to get it polling.

My approach is:

  • controller show action responds with JS

    def show
        @simulation = Simulation.find(params[:id])
    end
    
  • Then JS that does somthing like this..

`

// 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);
}

What the correct way of doing this? I've tried using coffeescript in the assets, but it is called on every controller element, I've tried embedding it in the html or trying to include it as a partial but I either get issues with rendering the ruby code I need too, or not getting access to enough of it, I've tried doing respond_to but it only gives me html. Can anyone help me solve this?

Edit:

Here is my show view:

<%= render 'simulation' %>

<%= link_to 'Back', simulations_path %>

and the included partial :

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

回答1:


My solution would be this:

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

Changes are that you have an element with class "some-element" with the attribute data-url set to the path that rails generate automatically for the update route. In your html you will have:

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

In your controller you should return @simulation as json.

Other advantages of this solution is that you can avoid embedding ruby in javascript which implies that the server sends the file for every request.

The polling is right, but other ways to do it would be with web sockets. In Rails you have some gems to do that, and in the near future Rails 5 will come along with ActionCable. Anyway I would continue with polling since it is way simpler than websockets.

The way this solution works:

  1. You request the show view and the server responds with the html, js and css files.
  2. Polling starts and every 10 seconds a request is sent to simulations#update (simulations controller/update action).There you can update and save your simulation and return the new values.
  3. In jquery's ajax.done you get the new data and you can update the client side data.

Hope it helps,

Santiago



来源:https://stackoverflow.com/questions/31952173/implementing-polling-for-rails-frontend-to-call-update

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!