0

所以我遇到的问题是让我的喜欢/不喜欢按钮在我的 Ruby on Rails 应用程序中使用 ajax 刷新,这是我的代码:

应用程序/视图/_comment.html.haml


- likes = comment.likes
%div.comment{id: "comment-#{comment.id}"}
  .comment-avatar
    .medium-user-avatar.avatar-canvas
      - if comment.user.avatar_url
        = image_tag comment.user.avatar_url(:medium)
      - else
        %span.medium-user-initials.initials-decoration
          = comment.user.avatar_initials
  %span.comment-username= link_to(comment.user_name, "#")
  %span.comment-body~ markdown(comment.body)
  .comment-time
    = time_ago_in_words(comment.created_at) + " ago"
    - if can? :like, comment
      = " · "
      - if likes.find_by_user_id(current_user.id).nil?
        = link_to "Like", like_comment_path(comment), method: :post, remote: true
      - else
        = link_to "Unlike", unlike_comment_path(comment), method: :post, remote: true
    - if comment.user == current_user
      = " · "
      = link_to "Delete", comment_path(comment), method: :delete, remote: true,
        :data => { :confirm => "Are you sure you want to delete this comment?" }
  - if likes.count > 0
    .comment-likes
      - likers = likes.map { |like| link_to(like.user_name, "#") }
      - if likers.length > 1
        - likers = likers.slice(0, likers.length - 1).join(", ").concat(" and " +     likers.slice(-1))
      - else
        - likers = likers[0]
      = "Liked by #{likers}".html_safe

应用程序/控制器/comments_controller.rb


class CommentsController < BaseController
  load_and_authorize_resource

  def destroy
    destroy!{ discussion_url(resource.discussion ) }
  end

  def like
    comment_vote = resource.like current_user
    Event.comment_liked!(comment_vote)
    #redirect_to discussion_url(resource.discussion )
    render :partial => "like"
    comment_likes
  end

  def unlike
    resource.unlike current_user
    #redirect_to discussion_url(resource.discussion)
    render :partial => "unlike"
    comment_likes
  end

  def comment_likes
    render :partial => "comment_likes"
  end
end

然后是 like、like 和 comment_likes 的 .js.erb 文件:

应用程序/视图/_like.js.erb


$(".comment-time a#like").html("<%= escape_javascript(render('.comment-time a#like'")

应用程序/视图/_unlike.js.erb


$(".comment-time a#unlike").html("<%= escape_javascript(render('.comment-time a#unlike'")

app/views/_comment_likes.js.erb


$(".comment-likes a##").html("<%= escape_javascript(render('.comment-likes a##'")

目前单击like 将更新数据库,但在页面刷新之前不会显示更改,我只想用ajax 刷新单个div。有关 div 的更多信息可能会有所帮助,因此 ruby​​ 创建 html 并包含在其中作为示例,或者当已经喜欢时,我只需要刷新这些 div 以显示数据库中的最新信息以及包含 http://localhost :3000/comments/7/不像 500 (内部服务器错误)"

如果这很重要,其余的脚本已经在coffeescript中完成了吗?我读到控制器功能应该使用 .js.erb 所以希望这不会影响它。(我确定我的 js.erb 是错误的)

4

2 回答 2

2

我不确定这是否是主要问题,但要解决的一件事是 .js.erb 文件中的渲染语句。

Rails 渲染方法需要 erb 模板或要渲染的操作作为其参数。你打电话时:

render('.comment-time a#unlike')

Rails 将尝试在您的视图路径中的某处查找名称为“.comment-time a#unlike”的模板,这可能会引发某种错误。确保您注意应用程序(服务器上)的 javascript(客户端)中发生的事情之间的区别。

因此,解决此问题的一种方法如下。首先检查您要更新视图的哪一部分,为简单起见,因为您已经有了 _comment 部分,让我们使用它。其次弄清楚它应该替换dom中的哪个部分,在你的情况下是具有当前评论ID的div。然后我们可以执行以下操作:

$("#comment-<%= @comment.id %>").replace_html(
  "<%= escape_javascript render('comments/comment', :comment => @comment) %>"
);

这将渲染_comment.html.erb部分 in app/views/comments,将结果(转义)插入到您的 (dis-)like.js.erb 中的 javascript 中,并将其发送回浏览器以执行。然后浏览器将replace_html在评论的 div 上(由 ID 指示。)

因为我们要替换整个评论 div,所以您可以对喜欢和不喜欢使用相同的方法。如果您需要节省带宽,您可以对其进行微调以仅重新渲染点赞按钮本身,但现在这将起作用。

于 2012-09-25T15:29:47.413 回答
1

问题是您的控制器不知道如何响应 ajax 请求。默认情况下,渲染方法将渲染 html.erb或在您的情况下为 html.haml模板。

除非您执行以下操作:

respond_to do |format|
  format.js { comment_likes }
end

现在,如果 ajax 请求进入 _comments_likes.js.erb 模板将被渲染。

如果您有更多这些 ajax 类型的问题,那么我们正在努力为 rails 重写 ajax 指南。

顺便说一句,请考虑清理您的视图。

于 2012-09-25T15:43:09.953 回答