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 => true
在link_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