2013-04-29 122 views
1

我已經嘗試閱讀大量有關該主題的文章和帖子,但我仍然困惑不解,無法弄清楚我需要做什麼。有人可以解釋我需要做什麼嗎?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 /> 

回答

0

您可以執行一個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" 
2

該項目結束了,但我想我應該記錄什麼,我如果任何人發現遇到這個問題在未來。已經有一段時間了,所以我不記得我做了什麼,但這是我能記得的最好的。

設置: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