关于下拉刷新,上拉加载在官方文档已经有了比较详细的说明,这里只说一下实际使用是需要注意的地方。
官方下拉刷新:http://dev.dcloud.net.cn/mui/pulldown/
官方上拉加载:http://dev.dcloud.net.cn/mui/pullup/
可以在HBuilder中直接【文件】->【新建】->【Html页面】,在下面选择"mui下拉刷新、上拉加载"
,这里默认创建的是双webview式的页面。在pullrefresh_main.html中包含页面的标题,pullrefresh_sub.html中包含了加载刷新的逻辑。
打开pullrefresh_sub.html页面,里面的pulldownRefresh是下拉刷新的回调函数,pullupRefresh是上拉加载的回调函数。业务主要围绕这两个写。
比如给定一个数据库中的表products,其中有ID,Name,AddTime。要求按AddTime降序排列。
上拉加载
默认的上拉加载是随机加载20个,每个的序号是总长度+1。现在的要求下,首次进入页面应该自动进行下拉加载20个项目。然后再次下拉时,应该按这个AddTime降序顺序,读取21-40个,后面依旧。这里就要考虑下怎么达到这个效果。
经验丰富的开发者一定想到了,可以在每次加载后保存下此次加载的AddTime最小的ID,然后ajax请求服务器的时候,附加上这个ID。在服务器端,收到ID后,先找到这个ID对应的时间,然后按AddTime降序从这个时间往后面取20个,返回给客户端。
所以就需要保存下每次加载的AddTime最小的ID,记为oldestID。注意,这个oldestID不能直接在页面中创建临时变量保存:
var oldestID;//错误的ID保存方式
/**
* 上拉加载具体业务实现
*/
function pullupRefresh() {
mui.ajax('http://www.test.com/mobile/products.ashx',{
data:{
id:oldestID
},
success:function(data){
//...
}
});
}
因为已加载的列表必然是按AddTime降序排列的,所以只要把oldestID作为属性保存在最后一项中就可以了
<li data-id="{id}">
...
</li>
全部代码如下:
/**
* 上拉加载具体业务实现,加载以前的
*/
function pullupRefresh() {
//新元素插入在table里面
var table = document.body.querySelector('.mui-table-view');
var last=table.querySelector('li:last-child');
var oldestID=last!=null?last.getAttribute('data-id'):'';
var self=this;
mui.ajax('http://www.test.com/mobile/products.ashx',{
data:{
id:oldestID
},
success:function(data){
if(data.Code<0){//有错误
plus.nativeUI.toast(data.Msg);return;
}
for(var i=0;i<data.Data.length;i++){
var item=data.Data[i];
//通过getItemElement函数将数据转换为可插入的Element元素
table.appendChild(getItemElement(item));
}
//如果列表为空,表示以前的产品加载完了
self.endPullupToRefresh(data.Data.length==0);
},error:function(){
self.endPullupToRefresh(false);
}
});
}
这里面Url是客户端响应ajax请求的地址,根据自己的实际情况改。
下拉刷新和上拉加载都需要吧json数据转换为Element插入到DOM,索性写个getItemElement做个转换:
var itemHtmlOri=
['<li class="mui-table-view-cell" data-id="{id}">',
'<div class="mui-table">',
'<div class="mui-table-cell mui-col-xs-3">',
'{name}',
'</div>',
'<div class="mui-table-cell mui-col-xs-9 mui-navigate-right">',
'{date}',
'</div>',
'</div>',
'</li>'].join('');
function getItemElement(item){
var box = document.createElement('div');
var itemHtml=itemHtmlOri;
itemHtml=itemHtml.replace(/{name}/g,item.Name)
.replace(/{date}/g,item.AddTime)
.replace(/{id}/g,item.Id);
box.innerHTML=itemHtml;
return box.firstChild;
}
下拉刷新
下拉刷新和上拉加载类似,也需要保存一个最新ID,每次下拉刷新的时候,向服务器请求这个ID,服务器先找到这个ID对应的AddTime,再看看有没有更新的Product,有就全部返回。
鉴于这两次请求基本相似,服务器干的活也差不多,唯一区别是前面找比给定ID旧的,这次找比它新的,所以为了代码复用,干脆再给服务器传一个参数type,告诉他找新的还是找旧的。这样两个函数就可以用一个地址了。
可以规定当type=1时找新的,type为空或null时找旧的,这样上面的代码就不用动了:
/**
* 下拉刷新具体业务实现,加载最新的
*/
function pulldownRefresh() {
//新元素插入到table中
var table = document.body.querySelector('.mui-table-view');
var first=table.querySelector('li:first-child');
var newestID=first!=null?first.getAttribute('data-id'):'';
mui.ajax('http://www.test.com/mobile/products.ashx',{
data:{
id:id,
type:'1'
},
success:function(data){
mui('#pullrefresh').pullRefresh().endPulldownToRefresh();
if(data.Code<0){//有错误
plus.nativeUI.toast(data.Msg);return;
}
for(var i=data.Data.length-1;i>=0;i--){
var item=data.Data[i];
table.insertBefore(getItemElement(item), table.firstChild);
}
},error:function(){
mui('#pullrefresh').pullRefresh().endPulldownToRefresh();
}
});
}
其他注意的
首次进入页面的时候是空的,应该自动上拉加载20项。这个模板中已经写好了:
if (mui.os.plus) {
mui.plusReady(function() {
setTimeout(function() {
mui('#pullrefresh').pullRefresh().pullupLoading();
}, 1000);
});
} else {
mui.ready(function() {
mui('#pullrefresh').pullRefresh().pullupLoading();
});
}