4.2 云开发JSON数据库
4.2.8 分页查询
在计算机互联网时代,很多页面底部分页导航按钮,有首页、上一页、第一页、第二页、尾页。
分页查询是指根据页码将每一页的数据查询出来。
在移动互联网时代,网页和应用都对网页进行优化,页面上拉触底时自动加载下一页。
分页查询示例代码如下:
Page({
/**
* 页面的初始数据
*/
data: {
pageData: [], // 已经获取的分页数据,通常会在视图层用wx:for列表渲染该数据
nextPage: 0 // 下拉触底时,应该获取下一页数据的页码,从0开始
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.getNextPageData() //进入页面时立即获得第0页的数据
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
this.getNextPageData() //页面下拉触底时获取下一页的数据
},
getNextPageData() {
const PAGE_COUNT = 20 //使用常量表示每一页显示的数据的数量
const db = wx.cloud.database() //获取数据库的引用
db.collection('testOne').count().then(res =>{ //集合中的记录的数量
const totalCount = res.total
const totalPages = Math.ceil(totalCount / PAGE_COUNT) //计算总页数,小数向上取整
if (this.data.nextPage < totalPages){ //当下一页存在
db.collection('testOne')
.skip(this.data.nextPage * PAGE_COUNT) //跳过已经获取的数据
.limit(PAGE_COUNT)
.get().then(res2 => { // 为了防止命名冲突,返回值命名为res2
// 将已有的pageData与新获得的20条数据合并成一个新的数组
const pageData = this.data.pageData.concat(res2.data)
this.setData({
pageData, // 将合并后的数据更新到data对象中
nextPage: this.data.nextPage + 1 // 将nextPage更新为下一页
})
console.log(res2.data)
console.log(this.data.nextPage)
})
} else {
console.log('no more data')
}
})
}
})
PAGE_COUNT = 20常量表示每一页显示的数据的数量,是微信小程序端的数量限制是20,服务端API的数量限制为100。
在分页查询时,首先需要在集合引用上使用count方法获取集合中所有记录的总数量,然后通过记录数量和PAGE_COUNT相除向上取整计算出总页数。
Math.ceil对小数向上取整,Math.floor对小数向下取整,Math.round对小数四舍五入。
计算出总页数,比较nextPage变量与总页数的大小,判断当前是否已经将数据全部获取完毕。数据没获取完,则在下拉触底时,通过集合引用上的get方法继续获取数据。
集合引用调用get方法前,通过skip方法指定需要跳过几条记录,在limit方法指定本次获取几条记录。limit上限20,服务端上限100。
获取到数据,用数组上的的concat方法将pageData与新获得20条数据合并成一个新的数组,同时页数加+1,并更新到data对象。
then方法代表使用了Promise风格的写法,好处是then方法函数中,this仍为这个页面对象。如果使用回调风格的写法,在success函数中,this值会被改变不再为原来的页面对象,需要在调用前将this对象提前记录下来。
成功运行非常开心,分享它打印在调试台数据,图片如下:
回调风格的写法的分页查询代码如下:
getNextPageData() {
const PAGE_COUNT = 20
const db = wx.cloud.database()
const _this = this //将this对象提前用变量记录下来
db.collection('testOne').count({
success(res) {
const totalCount = res.total
const totalPages = Math.ceil(totalCount / PAGE_COUNT)
if (_this.data.nextPage < totalPages){ //在success函数中需要用_this代替this
db.collection('testOne')
.skip(_this.data.nextPage * PAGE_COUNT)
.limit(PAGE_COUNT)
.get({
success(res2) { //使用回调风格的API
//在success函数中需要用_this代替this
const pageData = _this.data.pageData.concat(res2.data)
_this.setData({
pageData,
nextPage:_this.data.nextPage+1
})
console.log(_this.data.pageData)
console.log(_this.data.nextPage)
}
})
}else{
console.log('no more data')
}
}
})
}