【Ruby on Rails全栈课程】4.7 评论功能实现(六)--其他回复展开

简介: 、描述每条评论下面的回复条数最多显示两条,多于两条,回复下面会显示「更多n条回复 ↓」链接,每次点击此链接,展开8条回复,页面不刷新,需要配合ajax和js实现。2、实现功能(1)在routes.rb文件中添加路径,加上两个参数,:comment_id为回复所属的评论的id,point为此次点击为第几次点击

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 %>' οnclick='outIn(<%= @comment_id %>,<%=re.id%>)'> 回复</a><% if re.get_account_right(@current_user) %><a data-remote='true' href='/posts/delete_comment/<%= re.id %>' οnclick='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,也就是不加载任何内容。


目录
相关文章
|
7月前
|
前端开发 测试技术 数据库
使用Ruby on Rails进行快速Web开发的技术探索
【8月更文挑战第12天】Ruby on Rails以其高效、灵活和易于维护的特点,成为了快速Web开发领域的佼佼者。通过遵循Rails的约定和最佳实践,开发者可以更加专注于业务逻辑的实现,快速构建出高质量的Web应用。当然,正如任何技术框架一样,Rails也有其适用场景和局限性,开发者需要根据项目需求和个人偏好做出合适的选择。
|
7月前
|
前端开发 测试技术 API
揭秘Ruby on Rails的神秘力量:如何让你的Web应用飞起来?
【8月更文挑战第31天】Ruby on Rails(简称RoR)是一个基于Ruby语言的开源Web应用框架,自2005年发布以来,因简洁的语法、强大的功能和高效的开发效率而广受好评。RoR采用MVC架构,提高代码可读性和可维护性,拥有庞大的社区和丰富的库支持。本文通过示例代码展示其强大之处,并介绍RoR的核心概念与最佳实践,帮助开发者更高效地构建Web应用。
141 0
|
7月前
|
前端开发 API C++
在Ruby世界中寻找你的Web框架灵魂伴侣:Rails vs Sinatra
【8月更文挑战第31天】在Ruby的世界里,选择Web框架如同挑选衣物,需根据场合和需求。Rails与Sinatra是两大热门框架,前者以其“约定优于配置”理念和全面的功能成为企业级应用的首选;后者则以轻量级和灵活性著称,适用于快速原型开发和小规模应用。通过对比两者特性,如Rails的MVC架构与Sinatra的简洁API,我们可以看到它们各有所长。选择合适的框架,如同找到旅途中的最佳伙伴,让开发之路更加顺畅愉悦。这场探索之旅教会我们,没有绝对的好坏,只有最适合的选择。
82 0
|
7月前
|
安全 前端开发 数据安全/隐私保护
如何在Ruby on Rails中打造坚不可摧的OAuth认证机制
【8月更文挑战第31天】在构建现代Web应用时,认证与授权至关重要。本文介绍如何在Ruby on Rails中实现OAuth认证,通过使用`omniauth`和`devise` gems简化流程。首先安装并配置相关gem,接着在`User`模型中处理OAuth回调,最后设置路由及控制器完成登录流程。借助OAuth,用户可使用第三方服务安全地进行身份验证,提升应用安全性与用户体验。随着OAuth标准的演进,这一机制将在Rails项目中得到更广泛应用。
89 0
|
数据库 Ruby Java
ruby on rails 入门注意事项
<div class="markdown_views"> <h2 id="ruby-on-rails-入门注意事项">ruby on rails 入门注意事项</h2> <p>首先声明:本文不是ruby on rails的入门教程 <br> 入门教程可以参考: <br><a href="http://www.tutorialspoint.com/ruby-on-rails/r
1761 0
|
10月前
|
Ruby
|
10月前
|
JSON 数据格式 Ruby