Rails 3使用AJAX刷新页面

问题描述:

我已经尝试阅读大量有关该主题的文章和帖子,但我仍然困惑不解,无法弄清楚我需要做什么。有人可以解释我需要做什么吗?Rails 3使用AJAX刷新页面

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

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

  • _game.html.erb实际呈现游戏
  • show.html.erb只是增加了一个标题,然后使该部分,_game。
  • show.js.erb应该刷新页面。我真的不知道这是如何工作

我也启用了Jquery的与//= require等行(他们是在默认情况下已经有了)

编辑:我有阿贾克斯工作的联系,但我仍然不知道如何在一段时间后自动刷新。有任何想法吗?

show.html.erb:

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

show.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 /> 

您可以执行一个javascript setTimeout方法,它将请求show.js视图。

在您看来(或只针对特定页面呈现一个.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: "/games/" + data.gameId + "/whatever.js" 

该项目结束了,但我想我应该记录什么,我如果任何人发现遇到这个问题在未来。已经有一段时间了,所以我不记得我做了什么,但这是我能记得的最好的。

设置:remote => truelink_to参数将标记链接与一个特殊的标记,导致它自动变成一个AJAX链接由Rails unobtrusive JS。由于它是一个普通的HTML链接,直到JavaScript运行,不需要额外的努力就可以使页面在没有启用Javascript的情况下工作。

为了让这些AJAX链接起作用,你需要两件事。首先,你必须定义一个js.erb文件。在我的情况下,我在show.js.erb中有这个。

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

注意render @game是一个速记将渲染露出game@game参数的局部视图_game.html.erb。

其次,您需要您的控制器响应js格式。由于我的观点是通过展示行动呈现的,因此我需要为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