1

我已经尝试阅读有关该主题的大量文章和帖子,但我仍然感到困惑,无法弄清楚我需要做什么。有人可以准确解释我需要做什么吗?

我有一个 Rails 服务器(3.2.11),它的模型Game代表 Ra 游戏的当前状态。我games_controllershow显示游戏和doturn处理某人动作的方法。游戏视图显示游戏的当前状态并包含每个可能移动的链接,这些链接会提交回doturn操作。我的目标是通过 AJAX 让视图在设定的时间段后或单击其中一个链接时自动刷新。但尽我所能,我无法让任何一个工作。

我的视图当前在 /views/games 文件夹中设置如下。

  • _game.html.erb实际渲染游戏
  • show.html.erb只需添加一个标题,然后渲染部分,_game。
  • show.js.erb应该刷新页面。我不太确定这是如何工作的

我还使用//= requireetc 行启用了 Jquery(默认情况下它们已经存在)

编辑:我在链接上使用了 AJAX,但我仍然不知道如何在一定时间后使其自动刷新。有任何想法吗?

显示.html.erb:

<h1>Game <%= @game._id %></h1>
<div id="test"><%= render @game %></div>

显示.js.erb:

$('#test').html('<%= escape_javascript (render @game) %>')

游戏控制器

  # GET /games/1
  # GET /games/1.json
  def show
    @game = Game.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @game }
      format.js
    end
  end

  # POST /games
  def doturn
    error = Proc.new do |message|
      flash[:alert] = message
      return render :inline => "<%= flash[:alert] %>"
      #return redirect_to :back       #must return from method immediately
    end

    @game = Game.where(id: params[:id]).first
    if @game.nil?
      error.call "Game not found"
    end

    #all the game update logic here

    @game.save
    redirect_to :action => "show", :id => @game._id
  end

这是我的局部视图的简化版本。我删掉了很多渲染的东西,但它仍然具有所有重要的行为。我想我应该先尝试让这个视图工作,然后我可以稍后再添加回其余的代码。

<% game.game_players.each_with_index do |player, i| %>
<table>
  <tr><td>Player <%= i+1 %></td></tr>
  <tr><td>Suns: </td><td><%= player.suns %></td></tr>
  <tr><td>Pharaohs: </td><td><%= player.pharaohs %></td></tr>
</table><p>

  <% 
  make_linkt = lambda do |text, kwargs|
    concat link_to text, {:remote => true, :method => "post", :action => "doturn", :id => game, :player => i}.merge(kwargs) # ** requires ruby 2
    concat raw "<br/>"
  end

    if i == game.turn
        if game.god_status == 0
            make_linkt.call("Invoke Ra", :type=>"invoke")
              if game.auction_track.size < 8
                make_linkt.call("Draw tile", :type=>"draw")
            end
        else
                make_linkt.call("Done", :type=>"god", :vals=>[], :endturn=>1)
        end
  end
  %> 

<% end %>
<br />
4

2 回答 2

2

该项目已经结束,但我认为我应该记录我的发现,以防其他人将来遇到这个问题。已经有一段时间了,所以我不记得我到底做了什么,但这是我能记得的最好的。

:remote => true在参数中设置link_to将使用特殊标签标记链接,使其自动被 Rails 不显眼的 JS 转换为 AJAX 链接。由于在 javascript 运行之前它是一个普通的 html 链接,因此在没有启用 Javascript 的情况下不需要额外的工作来使页面正常工作。

为了使这些 AJAX 链接正常工作,您需要做两件事。首先,您必须定义一个 js.erb 文件。就我而言,我在 show.js.erb 中有这个。

$('#test').html('<%= escape_javascript (render @game) %>')

请注意,这render @game是一个简写,它将呈现部分视图 _game.html.erb ,其@game参数公开为game.

其次,您需要您的控制器响应 js 格式。由于我的视图是通过 show 操作呈现的,因此我需要为 show.js 添加一个响应。我将以下内容放在我的 games_controller 中。

  def show
    @game = Game.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @game }
      format.js
    end
  end

获得自动刷新更加复杂,因为 Rails 并没有为您提供魔法。我最终在 javascript 中创建了一个循环函数,以使用 AJAX 手动刷新页面。

我将以下内容放在我的视图中,show.html.erb

<script>

$(document).ready(function() {

  setInterval(function() {

      $.ajax({
          type: 'GET',
          url: '<%= url_for(:action => 'show_partial', :id => @game) %>',
          data: {},
          cache: false,
          success: function(result) {
              $('#test').html(result)
          }
      });


  }, 2000);

});
</script>

然后我向控制器添加了一个show_partial动作,以便 js 可以调用它。

  def show_partial
    @game = Game.find(params[:id])
    return render @game
  end
于 2013-05-11T12:54:35.527 回答
0

您可以执行将请求 show.js 视图的 javascript setTimeout 方法。

在您的视图中(或仅在显示游戏的特定页面呈现的 .js 资产中):

<script type="text/javascript>
    function updateGame(data){
      $.ajax({
        type: "GET",
        url: "/games/whatever-your-path-is.js",
        dataType: "script"
      });
    }
    setTimeout(updateGame({gameId: '<%= @game.id %>'}, 5000)
</script>

updateGame 中的数据变量将在 ajax 调用中可用,例如“生成”适当的 url,例如:带有 url 的行可以是:

url: "/games/" + data.gameId + "/whatever.js"
于 2013-04-30T04:39:24.913 回答