Жизнь переменных в Rails - PullRequest
2 голосов
/ 07 мая 2009

У меня есть следующий код:

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

Я хочу создать игру на странице, показываемой шоу, поэтому у меня будет много перемещений по Ajax, но пользователь никуда не кликает. Все действия контроллера будут вызываться из Javascript.

Я получил сообщение об ошибке @game, равной нулю. Это ноль даже в методе update_game_time Как сделать так, чтобы переменная @game оставалась действительной, пока пользователь находится на этой странице?

Ответы [ 4 ]

3 голосов
/ 09 мая 2009

Если вы хотите, чтобы объект @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
2 голосов
/ 07 мая 2009

Отправка запроса на сервер каждые 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 голосов
/ 07 мая 2009

Перед рендерингом вы должны переместить две строки из метода show в update_game_time. Иначе @game не определено, кроме как при рендеринге действия show.

1 голос
/ 07 мая 2009

Вам нужно передать переменную в парциальную, чтобы она была там видна.

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

, а затем получить доступ к нему в частичном виде так:

<div id=countdown> <%= game.running_time %></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...