我有以下代码:
def show
@game = $site.new_game_of_type(params[:id])
@game.start
end
def update_game_time
render :partial => 'countdown', :layout => false
end
和倒计时部分:
<div id=countdown> <%= @game.running_time %></div>
在show.html.erb中我有:
Time: <div id="countdown"> </div>
<%= periodically_call_remote(:frequency => 0.5,
:update => 'countdown', :url => {:action => :update_game_time}) %>
我想在show中显示的页面中创建一个游戏,所以我会在那里移动很多ajax但是用户不会在任何地方点击。控制器的所有操作都将从Javascript调用。
我得到@game为零的错误。即使在方法update_game_time中也是零 当用户在该页面中时,如何使@game变量保持有效?
答案 0 :(得分:3)
如果希望@game对象在请求之间保持不变,则需要将其存储在某处。有很多方法可以做到这一点(例如,你可以使它成为一个ActiveRecord对象并将其保存在数据库中)但它看起来像你想要使用会话。可以在http://www.quarkruby.com/2007/10/21/sessions-and-cookies-in-ruby-on-rails找到在Rails中使用会话所涉及的主要问题的一个很好的概述,但基本用法是:
def show
@game = $site.new_game_of_type(params[:id])
@game.start
session[:game] = @game
end
def update_game_time
@game = session[:game]
render :partial => 'countdown', :layout => false
end
答案 1 :(得分:2)
每0.5秒向服务器发出一个请求并不是一个好主意。
我的建议是加载running_time
一次,然后使用javascript来增加/减少它。
也许你可以这样做:
<div id=countdown><%= @game.running_time %></div>
在视图中然后使用一些javascript来更新计时器:
window.onload = function() {
var countdownDiv = document.getElementById('countdown');
var timerValue = parseInt(countdownDiv.innerHTML); // assuming that your running_time is an int (seconds)
var dateObj = new Date();
dateObj.setTime( timerValue*1000 );
countdownDiv.innerHTML = dateObj.getMinutes() + ":" + dateObj.getSeconds();
var timer = setInterval("dispalyTimer()", 1000);
dispalyTimer = function() {
dateObj.setTime( ( (dateObj.getTime()/1000) + 1 )*1000 );
countdownDiv.innerHTML = dateObj.getMinutes() + ":" + dateObj.getSeconds();
}
}
这只是一个基本的例子,但你明白了。无论如何,最好每半秒向服务器发出一次请求,这对于一个在客户端也可以很好地工作的计时器来说。
答案 2 :(得分:2)
在渲染之前,您应该将show
方法中的两条线移动到update_game_time
。否则@game
未定义,除了呈现show
操作时。
答案 3 :(得分:1)
您需要将变量传递给partial,以便在那里可见。
def update_game_time
render :partial => 'countdown', :layout => false, :locals => { :game => @game }
end
然后在部分中访问它:
<div id=countdown> <%= game.running_time %></div>