项目中用到一个下拉多选框,框内数据从后台获取,由于数据较多,导致接口反应时间较长且渲染速度较慢,所以采用分页请求数据形式,下拉到底部时进行分页请求,下面贴代码(由于采用按需加载js,所以没有controller):
先定义一个directive:
angular.module('app.directive').directive('pullRefresh', [function() {
return {
restrict: 'AE',
link: function(scope, ele, attr) {
ele.on('scroll', function() {
var scrollTop = ele[0].scrollTop;
//滚动条的高度
var scrollHeight = ele[0].scrollHeight;
//窗口的高度
var offsetHeight = ele[0].offsetHeight;
//内容可视区域的高度
if (scrollTop + offsetHeight >= scrollHeight) {
scope.$apply(attr.pullRefresh);
}
})
}
}
}])
页面上引用(这里用到bootstrap的dropdown):
<div class="dropdown">
<p ng-click="offerClick()" class="dropdown-toggle" data-toggle="dropdown">{{已选择内容}}</p>
<ul class="dropdown-menu" role="menu" scrolled="loadMore()">//这里的样式应有max-height:固定值;overflow-y:auto;
<li ng-repeat="vo in items" self-stop-propagation>
// self-stop-propagation 因为是下拉复选框,所以此处用于防止冒泡
<i class="fa fa-check-square" ng-class="{true:'active'}[vo.isSelect]"></i>{{vo.name}}
</li>
<li ng-show="busy">
<i class="">此处可用于显示加载动画</i>
</li>
</ul>
</div>
js:
$scope.currentPage = 0;
$scope.totalPages = 1;
$scope.busy = false;
$scope.firstReq = true;
$scope.offerClick = function(detailNET,dom){
if ($scope.firstReq) {
$scope.loadMore();//仅第一次点击时请求第一页数据
}
};
$scope.loadMore = function() {
if ($scope.currentPage < $scope.totalPages) {
$scope.currentPage++;
if ($scope.busy) {
return false;
}
$scope.busy = true;
// 请求后台服务器(API内容就不放了)
operationAPI.allList($scope.currentPage).then(function(result){
if (result.status == 0) { //数据正常返回时执行
$scope.busy = false;//防止重复请求
$scope.firstReq = false;//防止offerClick 的请求
$scope.itemScroll = result.offers;
$scope.items= $scope.items.concat($scope.itemScroll);//将请求页内的数据拼接到总数据中
$scope.totalPages = result.totalPages;
}
})
}
};
请求的具体逻辑如下:
默认下拉框不显示,点击p标签时显示下拉框并请求接口将第一页的返回值渲染到下拉框中(此处渲染会有延时,因为接口返回值需要时间,且仅在第一次点击时请求接口,之后的点击仅显示/隐藏下拉框);
滚动条到下拉框底部时请求第二页,渲染完成前显示loading动画,完成后隐藏;
继续下拉到底部继续请求,直到请求页数等于总页数不再请求。