Ajax用于post upvote/downvote(停止页面刷新)



我在Rails应用程序中使用"acts_as_votable"gem,这样用户就可以对帖子进行投票。我正在尝试添加Ajax功能,这样当用户投票支持帖子时,整个页面就不必刷新了。

我的赞成票/反对票链接可以点击并记录投票,但渲染没有刷新,票数仍然保持不变(我仍然需要刷新页面才能看到票数的变化)。

我可以看到我的运行日志这个错误:

Rendered posts/downvote.js.erb (3.4ms)
Completed 500 Internal Server Error in 77ms (ActiveRecord: 8.4ms)
ActionView::Template::Error (undefined method `id' for nil:NilClass):
1: $(document).ready(function(){
2:     $('#vote_<%= p.id %>').html("<%= escape_javascript render :partial => 'vote' %>");
3: });
app/views/posts/downvote.js.erb:2:in `_app_views_posts_downvote_js_erb__811382410496335987_70314739481440'
app/controllers/posts_controller.rb:44:in `downvote'

Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb (1.0ms)
Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb (0.7ms)
Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb (17.0ms)

这是我所拥有的:

路线.rb

resources :posts do 
member do
put "like", to: "posts#upvote"
put "dislike", to: "posts#downvote"
end
end

post_controller.rb

def upvote
@post = Post.find(params[:id])
@post.upvote_by current_user
respond_to do |format|
format.html { redirect_to :back }
format.js 
end
end
def downvote
@post = Post.find(params[:id])
@post.downvote_by current_user
respond_to do |format|
format.html { redirect_to :back }
format.js 
end
end

explore.html.erb(/views/pages/explore.html.erb)

<% if @posts.each do |p| %>
<div class="panel-body">
<p class="post-content"><%= auto_link(p.content, :html => { :target => '_blank' }) %></p>
<%= render :partial => '/posts/vote', :class => "vote", :locals => { p: p } %>
</div>
<% end %>

_vote.html.erb(/views/posts/_vote.html.erb)

<<div id="vote_<%= p.id %>" class="vote">
<%= link_to 'Vote Up', like_post_path(p), :class => "upvote", :method => :put, :remote => true %>
<span><%= p.score %></span>  <!--show the current vote-->
<%= link_to 'Vote Down', dislike_post_path(p), :class => "downvote", :method => :put, :remote => true %>
</div>

upvote.js.erb(/views/posts/upvote.js.erb)

$(document).ready(function(){
$('#vote_<%= p.id %>').html("<%= escape_javascript render :partial => 'vote' %>");
});

向下投票.js.erb(/views/posts/downwest.js.erb)

$(document).ready(function(){
$('#vote_<%= p.id %>').html("<%= escape_javascript render :partial => 'vote' %>");
});

我的javascript有问题吗,或者我呈现的东西有问题吗?提前谢谢。

  1. _vote.html.erb(/views/posts/_vote.html.erb)第一行中的"><<"将引发语法错误。

  2. 在*.js.erb文件中,只有来自控制器操作的@post,而不是像您的视图中那样的p。尝试更新如下:

upvote.js.erb(/views/posts/upvote.js.erb)

$(document).ready(function(){
$('#vote_<%= @post.id %>').html("<%= escape_javascript render :partial => 'vote', locals: { p: @post } %>");
});

向下投票.js.erb(/views/posts/downwest.js.erb)

$(document).ready(function(){
$('#vote_<%= @post.id %>').html("<%= escape_javascript render :partial => 'vote', locals: { p: @post } %>");
});

希望得到帮助。:)

答案就在错误中,javascript文件中的p变量为nil。

您之所以能够在html文件中使用p,是因为您正在循环浏览@posts集合,该集合在名为p的变量中提供每个帖子。

然而,在js文件中没有这样的循环,因此需要直接访问实例变量。

此外,当您在javascript文件中呈现_vote分部时,您没有提供p局部变量,您还需要包括它。

将downwote.js.erb代码更改为:

$(document).ready(function(){
$('#vote_<%= @post.id %>').html("<%= escape_javascript(render(:partial =>'vote', :locals => { p: @post })) %>");
});

最新更新