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

  • Is it live
  • Streaming with Rails 4
  • Server-sent events - Wikipedia
  • SEE on client side @ html5rocks

  • 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中点序列形成的多边形数量?

    下一篇: 在一个动作中呈现多个响应