数据分页
当数据库中数据非常多时,如果不分页,数据库查询的时间会比较长,用户等待的时间也会比较长,因此数据需要分批次展示。这时就需要用到数据分页功能。
分页的本质,就是在查询数据库时,通过指定查询条件,让数据库返回我们需要展示的数据。
分页功能的核心要素:
- 当前页。用户通过点击上一页或者下一页或者页码产生,客户端通过get参数方式传递到服务器端。
- 总页数。根据总页数判断当前页是否是最后一页,根据判断结果做出响应操作。总页数=总数据条数/每页数据条数,再将结果向上取整。
在userPage.js中,接收客户端传递过来的当前页参数。
由于当前页参数是由get方法传递过来的,所以就可以用req.query得到。
如果在函数开头部分写上
let page = req.query.page || 1;
res.send(page);
return;
那么浏览器中输入localhost/admin/user?page=数字,那么页面就会显示什么数字。
User.countDocuments(查询条件)
可以查询到符合条件的用户总数。查询条件为{}
时,返回所有用户的总数。
当没有传入页数的时候,默认页码是1.
let total = Math.ceil(count / pagesize);
实现了除法的向上取整,计算了总页数。
数据分页要用到的方法
limit()
限制查询结果的数量,传入每页显示的数据的数量
skip()
跳过了多少条数据的数量,传入1,则从第二条数据开始查询
但是,客户端传递的是当前页的页码,所以,服务端需要把当前页的页码转换为数据的开始位置。
比如,要查询第二页的数据,数据就是从10开始。那么根据页码得到数据的公式,就是(2-1)* 10 = 10.
数据开始查询位置 = (当前页 - 1) * 每页的条数
实现分页核心功能
//页码对应的数据查询的开始位置
let start = (page - 1) * pagesize;
//将用户信息从数据库中查询出来
let users = await User.find({}).limit(pagesize).skip(start);
此时,用户列表已经不会把所有的数据都展示出来了,它默认展示第一页的数据。输入
localhost/admin/user?page=2,则能看到第二页的数据。
在页面中添加分页器,并且为分页器的每一个按钮添加链接
在userPage.js中,在渲染用户列表模板的同时,要将分页的数据传入到模板当中,比如,当前有多少页,一共有多少页。
res.render('admin/user', {
users: users,
page: page,
total: total
});
这样,在模板中,就能够找到当前页和总页数了。
在views/user.art中找到分页器。
中间的页码,要根据总页数来决定有多少个。
<ul class="pagination">
<li>
<a href="/admin/user?page=<%=page-1%>">
<span>«</span>
</a>
</li>
<% for (var i = 1; i <= total; i++) {%>
<li><a href="/admin/user?page=<%=i%>">{{i}}</a></li>
<% } %>
<li>
<a href="/admin/user?page=<%=page-0+1%>">
<span>»</span>
</a>
</li>
</ul>
此时已经可以实现点击页码分页了。
下一页写成page-0+1
主要是因为-号带隐式类型转换,而+号不带。
接下来对当前页进行判断,看看它是否是最后一页,如果是,就把下一页按钮给给隐藏掉,同理,如果本页已经是第一页了,就不显示上一页按钮了。
<li style="display: <%= page-0+1 > total ? 'none' : 'inline;'%>">
<a href="/admin/user?page=<%=page-0+1%>">
<span>»</span>
</a>
</li>
应该使用inline而不使用block,否则会破坏原有样式。
此时,分页功能完成了