2014-01-21 12 views
7

Ich habe eine AJAX-Anfrage in meiner App Rails, die eine Variable aus meiner Controller-Aktion zurückgibt. Innerhalb der Controller-Aktion habe ich eine Schleife, die einige Zeit braucht, um durchzukommen.Schienen Ajax - render mehrere Antworten in einer Aktion

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

Ich möchte stattdessen die Ergebnisse in jeder Phase der Schleife zum js.erb Teil machen können, Warten auf die Schleife zu beenden. Ist dies möglich, ohne die Schleife zu unterbrechen und die Aktion vorzeitig zu beenden, bevor die Schleife beendet ist? Vielleicht so etwas wie dieses (Pseudo-Code, der falsch ist):

-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); 
+0

Vielleicht kann dies auf Ihre Frage in Beziehung gesetzt werden: http://stackoverflow.com/questions/1402757/how-to-break-out-from-a-ruby-block – scaryguy

+0

Danke, aber wird nicht automatisch die Schleife verlassen (bevor sie die nächste erreicht)? – diasks2

Antwort

3

render stream: true wird träge die Abfragen laden und es ihnen ermöglichen, nach dem Vermögen und das Layout ausgeführt erbracht wurden . Streaming funktioniert nur mit Vorlagen und nicht mit anderen Formen (z. B. json oder xml).

So, Sie haben kein Glück & Sie müssen ActionController::Live verwenden, die in Rail 4 & oben verfügbar ist. Live ist ein spezielles Modul in der ActionController-Klasse. Es ermöglicht Rails, einen Stream explizit zu öffnen und zu schließen. Hier wird der Pseudocode angepaßten mehr rubin wie & Vermeidung globale Variablen zu sein:

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 schlingt 1-list_size und Ausgang list_item sofort.

verwenden Sie dies, sollten Sie Server-Gesendete Ereignisse verwenden. Normalerweise müsste die Webseite fragen, ob Updates verfügbar sind. Bei serverseitigen Ereignissen werden die Aktualisierungen automatisch ausgeführt.

Sie bitte die folgenden Ressourcen verwenden, um mehr aboue Streaming, SSE & Ereignisquelle zu lernen:

0

Das wird nicht funktionieren, wenn Sie eine synchrone Verbindung haben. Sie müssen Websockets verwenden, um dieses Problem zu beheben. Websockets sind eine JavaScript-Implementierung von Sockets, die Ihnen die Möglichkeit bieten, eine biliterale Verbindung mit dem Client zu haben. So können Sie veranlassen, dass der Client einen Teil der Daten abruft, wenn Daten vorhanden sind.

Es gibt ein Ruby-Juwel namens Websocket-Rails, die Websockets in Schienen implementiert. Sie können es hier finden:

https://github.com/websocket-rails/websocket-rails

Das ist der Weg von zu gehen, wo Im Stehen ...