【问题标题】:Ajax for post upvote/downvote (stopping page refresh)用于发布 upvote/downvote 的 Ajax(停止页面刷新)
【发布时间】:2017-05-27 01:46:21
【问题描述】:

我在我的 Rails 应用程序中使用“acts_as_votable”gem,以便用户可以对帖子进行投票。我正在尝试添加 Ajax 功能,以便在用户投票时不必刷新整个页面。

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

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

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)

这是我所拥有的:

routes.rb

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

posts_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' %>");
});

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

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

我的 javascript 有什么问题,还是我渲染有问题?提前谢谢你。

【问题讨论】:

    标签: javascript ruby-on-rails ruby ajax acts-as-votable


    【解决方案1】:

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

    您能够在 html 文件中使用 p 的原因是因为您正在循环通过 @posts 集合,在名为 p 的变量中提供每个帖子。

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

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

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

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

    【讨论】:

    • 感谢 John 发现我的错误并为您提供解决方案!
    【解决方案2】:
    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 } %>");
    });
    

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

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

    希望对您有所帮助。 :)

    【讨论】:

    • 你太棒了 Nhã!非常感谢您完成这项工作并帮助我了解控制器的操作功能。
    猜你喜欢
    • 2013-11-28
    • 2020-03-05
    • 1970-01-01
    • 1970-01-01
    • 2015-03-01
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多