微信小程序 “万利商城”实战之八: 商品列表页的下拉刷新和上拉加载更多功能的实现

在手机上浏览商品信息的时候,刷新及分页的需求是由下拉和上拉来实现的, 如下图:

接下来就分别实现下拉刷新和上拉加载更多这两个功能,先看下拉刷新

首先在index.json这个文件中添加配置项,代码如下 :

1 {
2   "usingComponents": {},
3   "enablePullDownRefresh": true,
4   "backgroundTextStyle": "dark"
5 }

第2行代码是index.json文件中本来就有的, 我们添加的是第3、4行 , 第3行表示页面可以下拉刷新,

设置后用户在手机屏幕上下拉的时候会看到页面顶部有三个黑色的小圆点出现,见上图中红框处。

第4行是设置小圆点的颜色,有dark/light可选,具体用哪个根据实际项目的背景颜色来确定,

如果项目的背景色是浅色就设置成dark,深色背景用light 。

接下来我们来编码实现如何从服务器上抓取最新的数据后刷新页面,代码如下 :

  onPullDownRefresh:function(options)
  {
    this.initProductList();
  },

代码非常简单 , onPullDownRefresh:function(options){ } 是下拉刷新对应的函数(函数名称是微信小程序规定的),

下拉刷新的时候系统就会去执行这个函数,函数体只有一行代码 this.initProductList();

即调用之前onLoad( ) 函数调用过的代码,这个函数重新去抓取最新的服务器数据 ,

然后透过 _this.setData({productList:productLists}); 更新页面数据,用户就能看到最新的商品信息了。

注:这也是为什么要把抓取服务器数据并设置到页面的功能单独写在一个函数的原因,

onLoad()函数和onPullDownRefresh()函数都能调用, 实现了代码的复用 ,后期维护起来也方便。

 

 

再看上拉加载更多

和下拉刷新一样, 上拉加载更多也有一个对应的函数 onReachBottom:function(options)} ,

用户上拉页面后小程序会自动调用这个函数,我们只要在这个函数里面编写相应的代码就可以了。

从本质上来讲,上拉加载更多其实是一个分页的问题,每上拉一次, 就去服务器上抓取下一页的数据 ,

然后将抓取的数据和现有的数据合并起来在页面上显示出来 。不过这样会带来另一个问题 ,

随着下拉次数的增加, 页面上显示的数据会越来越多,必然导致页面显示越来越慢,

所以一般会设置一个极限值,比如最多显示300条数据后就给用户一个提示,停止执行继续上拉的操作。

根据上面的思路, 我们先要定义一个pageIndex的变量,初始值是1,

用户每执行一次上拉操作, 我们先给这个变量+1 ,然后把pageIndex+1后的值传递到服务器端,

服务器端收到这个值后去抓取相应分页的数据并返回给小程序端然后显示出来,

 

代码如下:

1 data: {
2     productList: [],
3     pageIndex:1
4   },
5  

在data这个属性中增加pageIndex变量, 初始值为1 , 表示第一进入页面的时候显示第1页的数据。

 

onReachBottom:function(options){ }函数的代码如下 :

 1 onReachBottom:function(options)
 2   {
 3     var _this=this;
 4     var tempIndex = this.data.pageIndex+1;
 5     this.setData({pageIndex:tempIndex});
 6 
 7     if ( _this.data.productList.length>300) 
 8     {
 9       wx.showToast({
10         title: '超过最大显示数量!',
11       })
12       return false;
13     }
14 
15     wx.request({
16       url: 'http://www.tm.com/webapi/products',
17       data:{'pageIndex':this.data.pageIndex},
18       method:'GET',
19       success:function(res){
20         //var products=res.data;
21         var products=[ 
22           {'productId':555,'productName':'女装T恤555','price':18.9,'originalPrice':38.9,'imageUrl':'../../images/product55.jpg'},
23           {'productId':666,'productName':'女装T恤666','price':15.9,'originalPrice':25.9,'imageUrl':'../../images/product66.jpg'},
24           {'productId':777,'productName':'女装T恤777','price':15.9,'originalPrice':25.9,'imageUrl':'../../images/product77.jpg'},
25           {'productId':888,'productName':'女装T恤888','price':15.9,'originalPrice':25.9,'imageUrl':'../../images/product88.jpg'},
26         ];
27         var newProductList = _this.data.productList.concat(products);
28         _this.setData({productList:newProductList});
29       }
30     })
31 
32   }

 

第4行读取pageIndex值并+1 , 第5行将新的值设置给pageIndex,此时pageIndex已经是+1后的值了。

第7-13行表示超过300条数据后就不执行了, 同时用wx.showToast( )这个API给用户一个提示。

第15行开始调用API wx.request( )抓取服务器数据。

第17行 data:{'pageIndex':this.data.pageIndex}, 需要传递pageIndex这个变量给服务器,

服务器端用Request.QueryString["pageIndex"]接收这个变量的值后获取分页数据。

第27行var newProductList = _this.data.productList.concat(products);

是将produceList的值和服务器端返回的数据products用javascript函数concat( )连接成一个新数组newProductList。

第28行用_this.setData({productList:newProductList});将newProductList设置给productList,完成数据在页面的显示。

 

注 :

1 . var products=[]的值依然是用mock的方式模拟的,

如果web服务器部署好了就应该用var products=res.data;来接收Web服务器返回的数据。

2 . 使用res.data获取Web服务器回传递值时需要用判断一下statusCode的值,代码如下:

 

1 success:function(res){
2         if(res.statusCode==200){
3           //var productObj=res.data;
4         }
5 }

 

因为小程序对Web服务器回传的值是照单全收的,即使是服务端传回的错误信息。

 

3 . 产品列表的图片地址 'imageUrl':'../../images/product55.jpg'是获取的本地地址, 这里是为了演示的方便,

如果web服务器部署好了应该用 'imageUrl':'http://www.tm.com/webapi/images/product55.jpg'这样的地址,

产品信息(包括图片)必须是来自于Web服务器!

 

posted @ 2020-11-09 11:13  屏风马  阅读(634)  评论(0编辑  收藏  举报