2009-05-07 8 views
2

私は次のコードを持っている:私が持っているshow.html.erbでライフ

<div id=countdown> <%= @game.running_time %></div> 

def show 
    @game = $site.new_game_of_type(params[:id]) 
    @game.start 
    end 

    def update_game_time 
    render :partial => 'countdown', :layout => false 
    end 

と部分カウントダウン

Time: <div id="countdown"> </div> 

<%= periodically_call_remote(:frequency => 0.5, 
    :update => 'countdown', :url => {:action => :update_game_time}) %> 

をIショーで表示されるページにゲームを作成したいので、そこには多くのAjaxが移動しますが、ユーザーはどこでもクリックしません。コントローラーのすべてのアクションはJavascriptから呼び出されます。

@gameがnilであるというエラーが発生しました。メソッドupdate_game_time でも、ユーザーがそのページにいる間に@game変数を有効なままにすることはできますか?

答えて

2

は、このような良いアイデアではありません。
私は、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(); 
    } 
} 

これは単なる基本的な例ですが、ポイントを取得します。とにかく、クライアント側でも非常にうまく動作するタイマーのために、毎秒の半分ごとにサーバーに要求するよりも優れています。

+0

答えをありがとう。 以前のクライアントイベントがなくても、サーバーがクライアントとの会話を開始できる方法はありますか? 0。5秒の更新は私のハックで定期的にサーバーを呼び出し、クライアントに情報を更新させます。それは私の知識の最高です – Jordi

+0

なぜサーバーは接続/会話を開始すべきですか?私は上手く理解できていない気がします。 * nixプラットフォームでは、サーバーから要求を出すためにcronジョブ(http://en.wikipedia.org/wiki/Cron)を使うことができますが、このアプローチが良いかどうかは分かりません。あなたは達成しようとしていることについて少し具体的になりますか? – andi

+0

私は基礎をなすエンジンを持っています。 Webインターフェイスを使用して、ユーザーに何が起こっているかを知り、プロセスとやりとりしたいと思っています。 ユーザーが新しいゲームを開始すると、エンジンはゲームの定義を読み、ユーザーインターフェイスを作成します。ゲームには時間制限があり、新しい着信データなどがあります。ユーザーに送信したいイベント。 これは可能ですが、私のポーリング手法は確かに効率的ではありません – Jordi

1

ここで変数を表示するには、変数を部分変数に渡す必要があります。その後、

def update_game_time 
render :partial => 'countdown', :layout => false, :locals => { :game => @game } 
end 

などのように、部分的にそれにアクセス:サーバーへの要求0.5秒ごとに作る

<div id=countdown> <%= game.running_time %></div> 
+0

私は 昇給@ game.running_time.to_s update_game_time内部のような何かを行う場合でも、私が手私が走ったことを伝えるメッセージ: nil.running_time.to_s ..... – Jordi

+0

ところで、少なくとも部分的にローカルになっているようです(無関係なコントローラで試しました)。先端に感謝します。 – Jordi

2

レンダリングの前に、showメソッドから2行をupdate_game_timeに移動する必要があります。そうでない場合は@gameは、showアクションのレンダリング時以外は定義されていません。

+0

これは私にレールコントローラのルールを覚えさせたので、これをアップしました: サーバへの各リクエスト==コントローラの新しいインスタンス。したがって、部分を取得するためのajax呼び出しは、(showが呼び出されていない)新しいインスタンスになるため、何かを行うための@game変数はありません。 – workmad3

3

@gameオブジェクトをリクエスト間で永続させたい場合は、どこかに格納する必要があります。これを行うにはさまざまな方法があります(たとえば、ActiveRecordオブジェクトを作成してデータベースに保持するなど)が、セッションを使用するように見えます。 Railsの内のセッションを使用することに関与する主要な課題の素敵な概要がhttp://www.quarkruby.com/2007/10/21/sessions-and-cookies-in-ruby-on-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 
関連する問題