Ajax + render :update

A ver si me aclaran esta
confusión
Todos los métodos Rails para Ajax usan un parámetro :update para indicar
que sección debe actualizarse con la respuesta del servidor.
Además la variante :update del render permite pasar un bloque y así
actualizar múltiples zonas, incluso ejecutar javascript por medio de page<<
Como respuesta a una petición ajax quiero actualizar una sección,
mostrar una seccion oculta y finalmente ejecutar un código javascript -
un periodical_call_remote para actualizar una barra de progreso
Me funciona a medias. Sí muestra la sección oculta y ejecuta el codigo
javascript, pero también dibuja el resultado de la petición en la
sección indicada en el :update del form_remote_tag, o sea además de
ejecutarlo, escribe en el browser el código fuente javascript que le
llega del server.
Y si remuevo el :update del form_remote_tag, entonces el código
javascript no se ejecuta!, siembargo los efectos visuales si se dan
Mi pregunta es, qué estoy haciendo mal?

PD: El código de render :update lo he probado tanto dentro del
controlador como en un template RJS obteniendo los mismos resultados
descritos.

Hola Esteban,

Esteban wrote:

A ver si me aclaran esta confusión

Todos los métodos Rails para Ajax usan un parámetro :update para indicar
que sección debe actualizarse con la respuesta del servidor.

Aunque es optativo su uso.

javascript no se ejecuta!, siembargo los efectos visuales si se dan
Mi pregunta es, qué estoy haciendo mal?

Creo que lo que estas haciendo mal es utilizar el :update y a su vez RJS
para una sola llamada ajax. Si utilizas RJS’s, no utilizes el parámetro
:update y viceversa.
Personalmente, siempre que puedo utilizo RJS’s para renderizar llamadas
ajax puesto que me resulta mucho más potente y dá más flexibilidad. En
lugar de utilizar un bloque en el :update podrías utilizar un RJS con:

page.hide “elemento_a_ocultar”
page.replace_html “elemento_a_actualizar”, “contenido”…
page.insert_html “periodically_call_remote”…

Aquí puedes encontrar practicamente todo lo necesario para trabajar con
RJS’s:
http://api.rubyonrails.com/classes/ActionView/Helpers/PrototypeHelper/JavaScriptGenerator/GeneratorMethods.html

PD: El código de render :update lo he probado tanto dentro del
controlador como en un template RJS obteniendo los mismos resultados
descritos.


Ror-es mailing list
[email protected]
http://lists.simplelogica.net/mailman/listinfo/ror-es

Saludos.

Xavier N. wrote:

Por lo tanto a priori sin :update deberia funcionar. Podrias por
favor enviar algo de codigo?

– fxn

Xavier,

Te paso mi código a ver si encuentras algo raro, te paso la variante con
platilla RJS en comentario viene para usar sin RJS. Uso backgroundRB
para iniciar una tarea de larga duración pero eso funciona bien. Te
agradezco cualquier ayuda que me puedas brindar.

En el Controlador

dibuja el form

def daily bonus
end

la acción que llama el submit del form

def daily_bonus_start
if request.xml_http_request? then
args = {:time => Abstract.sysdate, :userid => params[:userid]}
session[:daily_points_job_key] = MiddleMan.new_worker(
:class => :daily_points_worker,
:args => args) unless session[:daily_points_job_key]
else
redirect_to :action => :menu
end
end

def daily_bonus_start

if request.xml_http_request? then

args = {:time => Abstract.sysdate, :userid => params[:userid]}

session[:daily_points_job_key] = MiddleMan.new_worker(

:class => :daily_points_worker,

:args => args) unless session[:daily_points_job_key]

render :update do |page|

page.show ‘progress’

page.replace_html ‘progress_percent’, ‘0%’

page<<(periodically_call_remote(:url => {:action =>

‘daily_bonus_progress’}, :frequency => 2))

end

else

redirect_to :action => :menu

end

end

esta acción es la asociada al periodically_call_remote

def daily_bonus_progress
if request.xml_http_request? then
if session[:daily_points_job_key] then
progress =
MiddleMan.get_worker(session[:daily_points_job_key]).progress
progress_max =
MiddleMan.get_worker(session[:daily_points_job_key]).progress_max
progress_percent = (100 * progress / progress_max).to_i
render :update do |page|
page.call(‘progressPercent’, ‘progress_percent’,
progress_percent)
page.redirect_to(:action => ‘daily_bonus_done’) if
progress_percent >= 100
end
else
render :nothing => true
end
else
redirect_to :action => :menu
end
end

al llegar al 100% se llama esta acción

def daily_bonus_done
session[:daily_points_job_key] = nil
flash[:message] = ‘Daily Bonus calculation finished successfully’
redirect_to :action => :menu
end

En la vista

daily_bonus_start.rjs

page.show ‘progress’
page.replace_html ‘progress_percent’, ‘0%’
page<<(periodically_call_remote(:url => {:action =>
‘daily_bonus_progress’}, :frequency => 2))

daily_bonus.rhtml

<%= form_remote_tag :url => {:action => :daily_bonus_start} %>
<%= hidden_field_tag ‘token’, session.session_id %>
<%= submit_tag “Proceed”, :disabled => if @next_run == :running then
:disabled else nil end %>
<%= end_form_tag %>

On Feb 3, 2007, at 1:33 AM, Esteban wrote:

javascript, pero también dibuja el resultado de la petición en la
sección indicada en el :update del form_remote_tag, o sea además de
ejecutarlo, escribe en el browser el código fuente javascript que le
llega del server.
Y si remuevo el :update del form_remote_tag, entonces el código
javascript no se ejecuta!, siembargo los efectos visuales si se dan
Mi pregunta es, qué estoy haciendo mal?

Cuando uno pasa :update a form_remote_tag, se genera un objeto
Ajax.Updater. Este entiende que debe actualizar el elemento con el ID
que se pasa con lo que la llamada Ajax devuelve. Ademas, como se
genera con evalScripts:true, los s se evaluan. Por eso ves
que funciona salvo que el codigo termina por ahi.

En cambio, si no se pasa :update se genera un objeto Ajax.Request,
que tambien evalua el JavaScript, pero no trata de actualizar de por
si nada.

Por lo tanto a priori sin :update deberia funcionar. Podrias por
favor enviar algo de codigo?

– fxn