AJAX 更新微博post 投票up/down 部分只刷新最近的post
AJAX to update micropost vote up/down partial only refreshes the most recent post
使用Rails3、JRuby。
我想为我的 Rails 社交应用程序添加 "vote up" 和 "vote down" 评级,让用户基本上喜欢和不喜欢 post。这很好用,但是只要 post 被投票,就会刷新整个页面。为了解决这个问题,我想实现一个部分刷新,它只会更新 post 提要中的特定 post 分数。
我按照我通常的模式来实现 AJAX 部分刷新,但是,结果并不完全是我想要的。它不是刷新 post I like/dislike,而是用 post I 只是 liked/disliked 的新分数刷新最近的 post。
我已确定这是部分刷新问题,因为当我手动刷新整个页面时,每个 post 都有其正确的 like/dislike 分数(包括我打算更改的分数)。我认为问题在于我的页面使用 "do block" 将 posts 呈现到页面的方式。我的问题是,我无法弄清楚如何获得正确刷新我投票的 micropost 所需的行为。这是我的一些代码:
_micropost.html.erb(部分)
<% microposts.each do |mp| %>
<div class="profile_block gradient ">
<!-- Header -->
<header class="top-bar">
<small class="badge sharp">Post</small>
<!-- post/ article options -->
<% if mp.user_id == current_user.id %>
<%= link_to '<span class="glyphicon glyphicon glyphicon-cog"></span>'.html_safe, '#', class: "comment_link pull-right"%>
<% end %>
<%= link_to '<span class="glyphicon glyphicon glyphicon-heart"></span>'.html_safe, increment_micropost_path(mp.id), class: "comment_link pull-right", :remote => true%>
<%= link_to '<span class="glyphicon glyphicon glyphicon-thumbs-down"></span>'.html_safe, decrement_micropost_path(mp.id), class: "comment_link pull-right", :remote => true %>
<div id="global" class="pull-right badge"><%= render :partial => 'microposts/rating', :locals => {:micro => mp} %></div>
</header>
(....)
<% end %>
</div>
_home.html.erb
(....)
<div id="gf" class="left_col">
<%= render :partial => 'microposts/micropost', :locals => {:microposts => @microposts }, :remote => true %>
</div>
(....)
我的_rating.html.erb部分(显示信息的位)
<%= micro.rating.to_i %>
controller(我只展示增量方法,它们几乎相同
#increments micropost rating by 1
def increment
@micropost = Micropost.find(params[:id])
@increment = lambda { |micropost| micropost.update_attribute(:rating, micropost.rating.to_i + 1) }
@increment.call @micropost
respond_to do |format|
format.html {redirect_to root_url}
format.js
end
end
和对应的increment.js.html
$('#global').html("<%= escape_javascript render :partial => 'microposts/rating', :locals => {:micro => @micropost} %>");
我在上面提到过,micropost 的实际递增/递减功能工作正常 - 它只是使用 AJAX 重新呈现此信息,但未按预期运行。
任何想法,请分享。
原因是你的代码中有多个div#global
(因为each
循环),所以浏览器只会识别第一个。将 global
从 id 更改为 class 然后它应该可以工作。我还会将 data-num
属性添加到 div
并将其分配给数据库对象的 id
(不要与 HTML id
混淆)。像这样:
<div class="pull-right badge global" data-num="<%= mp.id %>"><%= render :partial => 'microposts/rating', :locals => {:micro => mp} %></div>
然后,在您的 increment.js.erb
中(我认为您的意思是 .js.html
...),将其更改为:
$('div.global[data-num="<%= @micropost.id %>"]').html("<%= escape_javascript render :partial => 'microposts/rating', :locals => {:micro => @micropost} %>");
这样,JavaScript 将始终知道要更新哪一个,因为它基于数据库 ID。
使用Rails3、JRuby。
我想为我的 Rails 社交应用程序添加 "vote up" 和 "vote down" 评级,让用户基本上喜欢和不喜欢 post。这很好用,但是只要 post 被投票,就会刷新整个页面。为了解决这个问题,我想实现一个部分刷新,它只会更新 post 提要中的特定 post 分数。
我按照我通常的模式来实现 AJAX 部分刷新,但是,结果并不完全是我想要的。它不是刷新 post I like/dislike,而是用 post I 只是 liked/disliked 的新分数刷新最近的 post。
我已确定这是部分刷新问题,因为当我手动刷新整个页面时,每个 post 都有其正确的 like/dislike 分数(包括我打算更改的分数)。我认为问题在于我的页面使用 "do block" 将 posts 呈现到页面的方式。我的问题是,我无法弄清楚如何获得正确刷新我投票的 micropost 所需的行为。这是我的一些代码:
_micropost.html.erb(部分)
<% microposts.each do |mp| %>
<div class="profile_block gradient ">
<!-- Header -->
<header class="top-bar">
<small class="badge sharp">Post</small>
<!-- post/ article options -->
<% if mp.user_id == current_user.id %>
<%= link_to '<span class="glyphicon glyphicon glyphicon-cog"></span>'.html_safe, '#', class: "comment_link pull-right"%>
<% end %>
<%= link_to '<span class="glyphicon glyphicon glyphicon-heart"></span>'.html_safe, increment_micropost_path(mp.id), class: "comment_link pull-right", :remote => true%>
<%= link_to '<span class="glyphicon glyphicon glyphicon-thumbs-down"></span>'.html_safe, decrement_micropost_path(mp.id), class: "comment_link pull-right", :remote => true %>
<div id="global" class="pull-right badge"><%= render :partial => 'microposts/rating', :locals => {:micro => mp} %></div>
</header>
(....)
<% end %>
</div>
_home.html.erb
(....)
<div id="gf" class="left_col">
<%= render :partial => 'microposts/micropost', :locals => {:microposts => @microposts }, :remote => true %>
</div>
(....)
我的_rating.html.erb部分(显示信息的位)
<%= micro.rating.to_i %>
controller(我只展示增量方法,它们几乎相同
#increments micropost rating by 1
def increment
@micropost = Micropost.find(params[:id])
@increment = lambda { |micropost| micropost.update_attribute(:rating, micropost.rating.to_i + 1) }
@increment.call @micropost
respond_to do |format|
format.html {redirect_to root_url}
format.js
end
end
和对应的increment.js.html
$('#global').html("<%= escape_javascript render :partial => 'microposts/rating', :locals => {:micro => @micropost} %>");
我在上面提到过,micropost 的实际递增/递减功能工作正常 - 它只是使用 AJAX 重新呈现此信息,但未按预期运行。 任何想法,请分享。
原因是你的代码中有多个div#global
(因为each
循环),所以浏览器只会识别第一个。将 global
从 id 更改为 class 然后它应该可以工作。我还会将 data-num
属性添加到 div
并将其分配给数据库对象的 id
(不要与 HTML id
混淆)。像这样:
<div class="pull-right badge global" data-num="<%= mp.id %>"><%= render :partial => 'microposts/rating', :locals => {:micro => mp} %></div>
然后,在您的 increment.js.erb
中(我认为您的意思是 .js.html
...),将其更改为:
$('div.global[data-num="<%= @micropost.id %>"]').html("<%= escape_javascript render :partial => 'microposts/rating', :locals => {:micro => @micropost} %>");
这样,JavaScript 将始终知道要更新哪一个,因为它基于数据库 ID。