问题
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:
- You request the show view and the server responds with the html, js and css files.
- 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.
- 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