美文网首页ruby小白课程实战--宠物论坛
【Ruby on Rails全栈课程】4.7 评论功能实现(六)

【Ruby on Rails全栈课程】4.7 评论功能实现(六)

作者: 808cb3be8e58 | 来源:发表于2019-01-18 15:24 被阅读32次
1、描述

每条评论下面的回复条数最多显示两条,多于两条,回复下面会显示「更多n条回复 ↓」链接,每次点击此链接,展开8条回复,页面不刷新,需要配合ajax和js实现。

2、实现功能
(1)在routes.rb文件中添加路径,加上两个参数,:comment_id为回复所属的评论的id,point为此次点击为第几次点击
get 'posts/show_replys/:comment_id/:point' => 'posts#show_replys'
(2)修改partial文件views/posts/_show_posts.html.erb,在「更多n条回复 ↓」a标签添加两个元素,分别是href元素(对应route文件添加的链接)、onclick元素(对应js方法addPoint)
<!--原代码-->
<a id="spread-out" name="1" data-remote="true" href="#">更多<%= @reply.count - 2 %>条回复 ↓</a>
<!--改为-->
<a id="spread-out" name="1" data-remote="true" href="/posts/show_replys/<%= comment.id %>/0" onclick="addPoint(this)">更多<%= @reply.count - 2 %>条回复 ↓</a>

代码解析:

  • onclick="addPoint(this)"
    this代表本次点击的a标签对象

如果a标签中同时有href、onclick两个元素,会先执行onclick、再执行href。
我们的思路:
点击「更多n条回复 ↓」链接,执行onclick元素对应的addPoint()方法,将href元素中的:point参数加1(:point参数初始为0),然后根据href链接,找到posts_controller里面的show_replys方法,向该方法传递参数:comment_id、:point。根据:comment_id参数,查找出该条评论下所有的回复,然后将:point参数保存到@point实例变量中。
然后我没创建show_replys.js.erb文件,每次点击「更多n条回复 ↓」链接都会调用这个文件,我们在这个文件中,能直接使用@point实例变量变量,得到此次点击为第几次点击,计算出此次应该显示出哪些回复,以及计算出剩余回复条数。

(3)编辑partial文件views/posts/_show_posts.html.erb,在下面的script标签里面添加下列代码
function addPoint(oldA){
  href = oldA.href;
  arr_point = href.split("/")[6];
  oldA.href = href.substring(0, href.length - 1) + (parseInt(arr_point)+ 1);
}

代码解析:
得到本次点击的a标签对象的href链接,在用split将链接分割为数字,其中索引为6的值为:point参数,将此参数加1,替代a标签的href元素中原先的:point参数。

(4)在posts_controller.rb文件中添加show_replys方法,用来查出对应评论的所有回复。
#显示评论下面的回复
def show_replys
  @comment_id = params[:comment_id]
  @point = params[:point].to_i
  #定义每次加载的条数
  @step = 8
  #找到comment_id代表的评论下面所有的回复
  @reply_part = Comment.where(re_comment_id:@comment_id,as_type:1)
end
(5)创建views/posts/show_replys.js.erb文件,添加下面代码
<% @reply_part[2+@step*(@point-1)...2+@step*@point].each do |re| %>
  //找到包含回复的那个div标签对象
  replyPage = document.getElementById("reply_page_<%= @comment_id %>");
  //新创建一个div标签,用来包含单个回复
  newReply = document.createElement("div");
  newReply.className = "re-reply";
  //将本次遍历的回复html内容插入到newReply标签中
  newReply.innerHTML = "<a><%= re.get_account_name %></a><% if re.re_reply_id.blank? %>:<% else %> 回复 <a><%= Comment.find(re.re_reply_id).get_account_name %></a> :<% end %><span id='content_<%= re.id %>'><% if re.status == 0 %><span><%= re.content %></span><% else %><span class='delete-content'>该评论已删除</span><% end %></span><div class='time_right'><%= re.get_created_at %><span id='time_<%= re.id %>'><% if re.status == 0 %><a id='reply<%= re.id %>' onclick='outIn(<%= @comment_id %>,<%=re.id%>)'> 回复</a><% if re.get_account_right(@current_user) %><a data-remote='true' href='/posts/delete_comment/<%= re.id %>' onclick='putDel(<%=re.id%>)'> 删除</a><% end %><% end %></span></div>"
  //每次循环,一条回复就会添加到replyPage代表的div标签里面。
  replyPage.appendChild(newReply);
<% end %>
//找到「更多n条回复 ↓」a标签
spreadOut = document.getElementById("spread-out");
//计算目前还剩多少条回复没有展示
<% space = @reply_part.count - @step*@point - 2 %>
<% if space > 0 %>
  //如果还有回复没有展示,则显示没有展示的条数
  spreadOut.innerHTML = "更多<%= space %>条回复 ↓"
<% else %>
  //如果回复全部展示了,则不显示「更多n条回复 ↓」a标签
  spreadOut.style.display = "none";
<% end %>

代码解析:

  • <% @reply_part[2+@step*(@point-1)...2+@step*@point].each do |re| %>
    实例@reply_part代表某个评论所有的回复对象集合,@step代表每次加载的条数,@point代表本次为第几次点击,@reply_part[2+@step*(@point-1)...2+@step*@point]表示本次点击需要加载的@step条回复的集合,用了区间(Range)知识点。
    比如我是第一次点击「更多n条回复 ↓」链接,@point就为1,@step我们定义为8,公式为@reply_part[2+8*0...2+8*1]计算出@reply_part[2...10],那么就会取@reply_part对象集合索引为2到9的数据,即第3条到第10条数据。
3、整理思路

我们再来整理一下点击更多回复链接之后,程序到底是怎样执行的。

  • 点击「更多n条回复 ↓」链接,程序根据routes.rb文件中的get 'posts/show_replys/:comment_id/:point' => 'posts#show_replys'代码找到
    posts_controller.rb文件中的show_replys方法

  • posts_controller.rb文件中的show_replys方法。获取到:comment_id、:point参数,并将相应的数据查出。

  • 数据查出后,会执行与show_replys同名的js.erb文件(即show_replys.js.erb文件)将需要展示的回复通过js插入到_show_posts.html.erb文件id为reply_page_<%= comment.id %>的标签中

  • 浏览器页面会局部更新,将更多回复展示出来。

扩展知识:js.erb文件
在a标签中设置data-remote="true",实现ajax,这样在执行完href链接对应在controller中的的action方法后,如果有与action同名的js.erb文件,会执行这个文件。如果没有同名的js.erb文件,会render到head,也就是不加载任何内容。

相关文章

网友评论

    本文标题:【Ruby on Rails全栈课程】4.7 评论功能实现(六)

    本文链接:https://www.haomeiwen.com/subject/nijidqtx.html