render multiple responses in one action
I have an ajax request in my rails app that returns a variable from my controller action. Inside the controller action I have a loop that can take some time to get through.
Controller
def myAction
$j = 1
until $j > list_size do
array << { :foo => $j }
$j +=1;
end
@myvariable = array.to_json
end
myAction.js.erb
var myVariable = JSON.parse("<%= escape_javascript(raw @myvariable) %>");
for (var k = 0; k < myVariable.length; k++) {
$("#myDiv").append(myVariable[k].foo);
}
I want to be able to render the results at each stage of the loop to the js.erb partial instead of waiting for the loop to finish. Is this possible without breaking the loop and ending the action prematurely before the loop finishes? Maybe something like this (pseudo code that is wrong):
Controller
def myAction
$j = 1
until $j > list_size do
array << { :foo => $j }
render array.to_json
$j +=1;
end
end
myAction.js.erb
var myVariable = JSON.parse("<%= escape_javascript(raw @myvariable) %>");
$("#myDiv").append(myVariable.foo);
render stream: true
will lazily load the queries and allow them to run after the assets and layout have been rendered. Streaming only works with templates and not any other forms (such as json or xml).
So, you are out of luck & you will have to use ActionController::Live
which is available in Rail 4 & above. Live is a special module included in ActionController class. It enables Rails to open and close a stream explicitly. Here is the pseudo code adaptated to be more ruby-like & avoiding global variables:
class MyController < ActionController::Base
include ActionController::Live
def action
(1..list_size).each do |list_item|
response.stream.write("{ "foo": #{list_item} }")
end
ensure
response.stream.close
end
end
Above code will loop from 1 to list_size
and output each list_item immediately .
to you use this, you should use Server-Sent Events. Normally, the web page would have to ask if any updates were available. With server-sent events, the updates come automatically.
Please use the following Resources to learn more aboue Streaming, SSE & Event Source:
API Docs - ActionController::Live
Railscast Paid
This wont work when you have a synchronous connection. You need to use websockets to handle this problem. Websockets are a javascript implementation of Sockets that give you the oppertunity to have a biliteral connection with the client. So you can cause the client to fetch a part of the data when there is data and so on.
There is a ruby gem called websocket-rails which implements websockets in rails. You can find it here:
https://github.com/websocket-rails/websocket-rails
Thats the way to go from where Im standing...
链接地址: http://www.djcxy.com/p/18722.html上一篇: 如何计算2D中点序列形成的多边形数量?
下一篇: 在一个动作中呈现多个响应