学习Angularjs分页指令


Posted in Javascript onJuly 01, 2016

在项目中许多页面都用到了分页,然后每个页面都有许多重复的分页代码,于是自己写了一份简易的分页指令,简化页面的代码,且容易维护,写在博客中当做备份,方便以后查阅。
以下是定义指令及其应用的步骤:

1.指令定义
定义一个js文件,page-directive.js,用来写分页的指令代码,这个文件中包含了分页的模板,以下是js文件中的所有代码:

'use strict';
(function () {
 angular.module('template/pageInit/pageInit.html', []).run([
  '$templateCache',function($templateCache) {
   $templateCache.put('template/pageInit/pageInit.html',
    '<ul class="pagination-main">\n'+
    ' <li class="prev-page" ng-class="{disabled:pageData.currentPage==1}" title="首页">\n'+
    '  <a href="javascript:void(0);" ng-click="on_loadPage(1)"><span class="fa fa-fast-backward"></span></a>\n'+
    ' </li>\n'+
    ' <li class="prev-page" ng-class="{disabled:pageData.currentPage==1 }">\n'+
    '  <a href="javascript:void(0);" ng-click="on_prev()" title="上一页"><span class="fa fa-step-backward"></span></a>\n'+
    ' </li>\n'+
    ' <li class="data-page" ng-repeat="page in pageData.pages" ng-class="{\'first-page\': page==1, \'last-page\': page==pageData.totalPage}">\n'+
    '  <a ng-if="page!=\'...\'" href="javascript:void(0);" ng-class="{\'bg-custom\': page==pageData.currentPage}" ng-click="on_loadPage(page, tabData)">{{ page }}</a>\n'+
    '  <a ng-if="page==\'...\'" href="javascript:void(0);" ng-class="{\'bg-custom\': page==pageData.currentPage}" ng-click="">{{ page }}</a>\n'+
    ' </li>\n'+
    ' <li class="next-page" ng-class="{disabled:pageData.currentPage==pageData.totalPage}">\n'+
    '  <a href="javascript:void(0);" ng-click="on_next()" title="下一页"><span class="fa fa-step-forward"></span></a>\n'+
    ' </li>\n'+
    ' <li class="skip-page"><div><input type="text" placeholder="" ng-model="inpage">\n'+
    '  <input type="button" value="跳转" ng-click="on_loadPage(inpage)"></div>\n'+
    ' </li>\n'+
    ' <li class="data-num"><a class="cursor-text" href="#"><span>共{{pageData.count}}条</span></a></li>\n'+
    '</ul>\n'+
    ''
   );
  }
 ]);
 angular.module('pageInit', ['template/pageInit/pageInit.html'])
  .directive('pageInit',['pageinitTemplate', function(pageinitTemplate) {
   return {
    restrict  : 'AE',
    templateUrl: function (tElement, tAttrs) {
     return tAttrs.templateUrl || pageinitTemplate.getPath();
    },
    replace  : true,
    scope   : {
     pageData    : '=',
     prev      : '&',
     next      : '&',
     loadPage    : '&'
    },
    link      : function(scope, element, attrs) {
     scope.on_prev = function() {
      if(scope.prev) {
       scope.prev();
      }
     };
     scope.on_next = function() {
      if(scope.next) {
       scope.next();
      }
     };
     scope.on_loadPage = function(page) {
      scope.inpage = undefined;
      if(scope.loadPage) {
       scope.loadPage({page: page});
      }
     };
    }
   };
  }])
  .provider('pageinitTemplate', function () {
   var templatePath = 'template/pageInit/pageInit.html';
   this.setPath = function (path) {
    templatePath = path;
   };

   this.$get = function () {
    return {
     getPath: function () {
      return templatePath;
     }
    };
   };
  });
}).call(window);

2.分页样式控制
建议写在单独的.css文件中,首先新建pageSync.css文件,以下是具体样式

.pagination-main {
 display: inline-block;
 padding-left: 0;
 margin: 0 0;
 border-radius: 4px;
 vertical-align: middle;
}
.pagination-main li.prev-page > a {
 border: 0;
}
.pagination-main li.next-page > a {
 border: 0;
 border-left: 1px;
 margin-left: 0;
}
.pagination-main li.first-page > a {
 border-top-left-radius: 0;
 border-bottom-left-radius: 0;
}
.pagination-main li.last-page > a {
 border-top-right-radius: 0;
 border-bottom-right-radius: 0;
}
.pagination-main li div {
 width: 80px;border: 1px solid #DDDDDD;background-color: #ffffff;float: left;padding: 0;
}
.pagination-main li.skip-page input[type='text'] {
 width: 24px;height: 20px;border: 0;text-align: center;
}
.pagination-main li.skip-page input[type='button'] {
 padding: 0 4px 1px 10px;border: 0;border-left: 1px solid #dddddd;background-color: #ffffff
}
.pagination-main li.data-num > a {
 border: 0;
 margin-left: 0;
}
.pagination-main > li {
 display: inline;
}
.pagination-main > li:first-child > a,
.pagination-main > li:first-child > span {
 /*margin-left: 0;
 border-top-left-radius: 4px;
 border-bottom-left-radius: 4px;*/
}
.pagination-main > .active > a,
.pagination-main > .active > span,
.pagination-main > .active > a:hover,
.pagination-main > .active > span:hover,
.pagination-main > .active > a:focus,
.pagination-main > .active > span:focus {
 z-index: 2;
 color: #fff;
 cursor: default;
 background-color: #428bca;
 border-color: #428bca;
}
.pagination-main > li > a,
.pagination-main > li > span {
 position: relative;
 float: left;
 /*padding: 6px 12px;*/
 padding: 1px 8px;
 margin-left: -1px;
 line-height: 1.42857143;
 color: #428bca;
 text-decoration: none;
 background-color: #fff;
 border: 1px solid #ddd;
}
.pagination-main > .disabled > span,
.pagination-main > .disabled > span:hover,
.pagination-main > .disabled > span:focus,
.pagination-main > .disabled > a,
.pagination-main > .disabled > a:hover,
.pagination-main > .disabled > a:focus {
 color: #999;
 cursor: not-allowed;
 background-color: #fff;
 border-color: #ddd;
}

3.分页查询方法
我在factory中自定义了分页查询的方法,共用,方便代码的维护。在angular中与后台的交互默认是异步的,我这里写成同步查询了,首先定义js文件pageSync.service.js,以下是factory的全部内容:

'use strict';
angular.module('app').factory('PageSync', ['$http', '$q', function Page($http, $q) {
 var rowCollectionPage = [];
 var totalPage = 1;
 var pages = [];
 var endPage = 1;
 var load = function(url, currentPage, pageSize,deferred) {
  var json = {rowCollectionPage: [], totalPage: 1, currentPage:currentPage ? currentPage:1, pages: []};
  $http.get(url).success(function(rows) {
   rowCollectionPage = setPageRow(rows.list, pageSize);
   // 获取总页数
   totalPage = Math.ceil(rows.count / pageSize);
   endPage = totalPage;
   // 生成数字链接
   if (totalPage <= 7) {
    pages = getPagesLow(totalPage);
   } else {
    pages = getPagesHigh(currentPage, totalPage);
   }
   json.rowCollectionPage = rowCollectionPage;
   json.totalPage = totalPage==0 ? 1 : totalPage;
   json.currentPage = currentPage;
   json.pages = pages;
   json.count = rows.count;
   json.pageSize = pageSize;
   /**
    * 自定义字段,初始化的时候为before,只要经过该分页方法,则字段值变为after
    * before表示未经过该分页方法,after表示经过该分页方法,
    * 前台页面加载的规则:为before时表示表格无数据,为after且pataData.count==0时无数据,否则视为有数据,
    * 也可以说是记录的一个时间状态(访问数据前及返回数据后)
    */
   json.loadTime = 'after';
   deferred.resolve(json);
  });
  return deferred.promise;
 };
 // 总页数小于等于7时 显示所有的页数
 var getPagesLow = function(totalPage) {
  var temp = [];
  for (var i=1; i<totalPage+1; i++) {
   temp.push(i);
  }
  return temp;
 };
 // 总页数大于7时 根据当前页获取7个页码数
 var getPagesHigh = function(currentPage, totalPage) {
  var temp = [];
  if (currentPage < 4) {
   temp = [1, 2, 3, 4, 5, '...', totalPage];
  } else if ((totalPage - currentPage) <= 3) {
   temp = [
    totalPage - 6, totalPage - 5, totalPage - 4,
    totalPage - 3, totalPage - 2, totalPage - 1, totalPage
   ];
  } else {
   temp = [
    currentPage - 2, currentPage - 1, currentPage,
    currentPage + 1, currentPage + 2, '...', totalPage
   ];
  }
  return temp;
 };
 // 项目中table的高度是根据浏览器窗口的高度计算的来的,是动态的
 // 因为要把分页固定在table最下方,所以无数据的用空行进行代替
 var setPageRow = function(rowArr, pageSize) {
  var temp = [];
  if (rowArr != undefined) {
   for (var i = 0; i < rowArr.length; i++) {
    temp.push(rowArr[i]);
   }
   for (var j = 0; j < pageSize - rowArr.length; j++) {
    temp.push({});
   }
  } else {
   for (var k = 0; k < pageSize; k++) {
    temp.push({});
   }
  }
  return temp;
 };
 return {
  load: function(url, currentPage, pageSize) {
   var deferred = $q.defer();
   url += '&' + currentPage + '&' + pageSize;
   return load(url, currentPage, pageSize, deferred);
  },
  next: function(url, currentPage, pageSize) {
   var deferred = $q.defer();
   if (currentPage < endPage) {
    currentPage++;
   }
   url += '&' + currentPage + '&' + pageSize;
   return load(url, currentPage, pageSize, deferred);
  },
  prev: function(url, currentPage, pageSize) {
   var deferred = $q.defer();
   currentPage--;
   url += '&' + currentPage + '&' + pageSize;
   return load(url, currentPage, pageSize, deferred);
  },
  loadPage: function(url, currentPage, pageSize, page) {
   var deferred = $q.defer();
   if (currentPage != page) {
    currentPage = page;
    url += '&' + currentPage + '&' + pageSize;
    return load(url, currentPage, pageSize, deferred);
   }
  }
 }
}]);

4.使用指令

1).页面上的代码:

我的代码中分页是写在table中的tfoot里面了,prev()、next()、loadPage(page)均为在页面对应的controller中定义的方法

<table>
<thead>
 <tr>
  <th>序号</th>
  <th>列名1</th>
  <th>列名2</th>
  <th style="width: 150px;text-align: center;">操作</th>
 </tr>
</thead>
<tbody>
 <tr ng-if="!noTableData" ng-repeat="row in pageData.rowCollectionPage">
  <td>{{!!row.id ? $index+1+(pageData.currentPage-1)*pageSize : ''}}</td>
  <td>{{row.args1}}</td>
  <td>{{row.args2}}</td>
  <td style="text-align: center;"><a href='#'>修改</a></td>
 </tr>
 <tr ng-if="noTableData" ng-repeat="data in pageData.rowCollectionPage">
  <td ng-if="$index == 0" colspan="4" style="text-align: center;">没有数据!</td>
  <td ng-if="$index != 0" colspan="4"></td>
 </tr>
 </tbody>
<tfoot>
 <tr>
  <td style="text-align: center;" colspan="6">
   <div>
    <page-init page-data="pageData" prev="prev()" next="next()" load-page="loadPage(page)"></page-init>
   </div>
  </td>
 </tr>
</tfoot>
</table>

2).controller中的代码

首先要引用factory,将PageSync在controller中引用,如下:

angular.module('app').controller('MyCtrl', function(PageSync) {});

在分页查询之前要做一些准备工作:

//pageData中设置分页数据集合、总页数、页码集合、数据总数,loadTime为自定义的参数,用来记录时间状态(访问数据前及返回数据后)
$scope.pageData = {rowCollectionPage: [], totalPage: 1, currentPage:1, pages: [],count: 0, loadTime: 'before'};
// 这里用来计算table的高度,根据实际情况来。
$scope.tabHeight = $scope.height-48-37-10-42-5;
// 计算实际中一页有多少行数据
$scope.pageSize = parseInt(($scope.tabHeight-15-34-34-39)/34);

然后再controller中写如下的方法

// 分页查询
$scope.load = function(row) {
 $scope.surgeonPageData.rowCollectionPage = Common.setPageRow([],$scope.pageSize);
 $scope.noSurgeonData = false;
 $scope.surgeonPageData.loadTime = 'before';
 PageSync.load(url, $scope.pageData.currentPage, $scope.pageSize).then(function(data) {
  $scope.pageData = data;
  if(($scope.pageData.loadTime=='after'&& $scope.pageData.count==0) || $scope.pageData.loadTime=='before') {
   $scope.noTableData = true;
  }
 });
};
// 下一页
$scope.next = function() {
 if ($scope.pageData.currentPage < $scope.pageData.totalPage) {
  PageSync.next(url, $scope.pageData.currentPage, $scope.pageSize).then(function(data) {
   $scope.pageData = data;
  });
 }
};
// 上一页
$scope.prev = function() {
 if ($scope.pageData.currentPage > 1) {
  PageSync.prev(url, $scope.pageData.currentPage, $scope.pageSize).then(function (data) {
   $scope.pageData = data;
  });
 }
};
// 点击页码跳转
$scope.loadPage = function(page) {
 $scope.inpage = undefined;
 var intPage;
 if (typeof page == 'string') {
  if(page!="") {
   intPage = parseInt(page, 10);
  } else {
   intPage = 0;
  }
 } else {
  intPage = page;
 }

 if ($scope.pageData.totalPage <= 1) {

 } else if (intPage == undefined || intPage == null) {
  alert('请填写跳转页码!');
 } else if(intPage <= 0 || intPage > $scope.pageData.totalPage) {
  alert('跳转页码应大于0,小于总页数'+$scope.pageData.totalPage);
 } else if ($scope.pageData.currentPage != page) {
  PageSync.loadPage(url, $scope.pageData.currentPage, $scope.pageSize, page).then(function (data) {
   $scope.pageData = data;
  });
 }
};

5.结果
最终的实现效果如下图:

学习Angularjs分页指令

学习Angularjs分页指令

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Extjs学习笔记之六 面版
Jan 08 Javascript
JavaScript高级程序设计 读书笔记之八 Function类及闭包
Feb 27 Javascript
用jquery实现点击栏目背景色改变
Dec 10 Javascript
extjs 3.31 TreeGrid实现静态页面加载json到TreeGrid里面
Apr 02 Javascript
jquery 实现上下滚动效果示例代码
Aug 09 Javascript
javascript date格式化示例
Sep 25 Javascript
jQuery中$.fn的用法示例介绍
Nov 05 Javascript
JQueryiframe页面操作父页面中的元素与方法(实例讲解)
Nov 19 Javascript
在javascript中,null>=0 为真,null==0却为假,null的值详解
Feb 22 Javascript
js实现华丽的九九乘法表效果
Mar 29 Javascript
浅谈Node框架接入ELK实践总结
Feb 22 Javascript
解决vue-router 二级导航默认选中某一选项的问题
Nov 01 Javascript
仿Angular Bootstrap TimePicker创建分钟数-秒数的输入控件
Jul 01 #Javascript
精彩的Bootstrap案例分享 重点在注释!(选项卡、栅格布局)
Jul 01 #Javascript
很棒的Bootstrap选项卡切换效果
Jul 01 #Javascript
AngularJS优雅的自定义指令
Jul 01 #Javascript
如何解决手机浏览器页面点击不跳转浏览器双击放大网页
Jul 01 #Javascript
再谈Javascript中的基本类型和引用类型(推荐)
Jul 01 #Javascript
JavaScript中有关一个数组中最大值和最小值及它们的下表的输出的解决办法
Jul 01 #Javascript
You might like
PHP执行linux系统命令的常用函数使用说明
2010/04/27 PHP
php实现获取文件mime类型的方法
2015/02/11 PHP
基于jQuery实现表格数据的动态添加与统计的代码
2011/01/31 Javascript
node.js中的fs.chown方法使用说明
2014/12/16 Javascript
BootStrap智能表单demo示例详解
2016/06/13 Javascript
jQuery基础_入门必看知识点
2016/07/04 Javascript
js删除数组元素、清空数组的简单方法(必看)
2016/07/27 Javascript
Bootstrap CSS组件之输入框组
2016/12/17 Javascript
Angular的$http的ajax的请求操作(推荐)
2017/01/10 Javascript
vue 详情跳转至列表页实现列表页缓存
2019/03/27 Javascript
微信小程序如何利用getCurrentPages进行页面传值
2019/07/01 Javascript
layui table去掉右侧滑动条的实现方法
2019/09/05 Javascript
js 实现watch监听数据变化的代码
2019/10/13 Javascript
微信小程序加载机制及运行机制图解
2019/11/27 Javascript
Angular5整合富文本编辑器TinyMCE的方法(汉化+上传)
2020/05/26 Javascript
详解Python3中yield生成器的用法
2015/08/20 Python
Python实现可设置持续运行时间、线程数及时间间隔的多线程异步post请求功能
2018/01/11 Python
Python3.遍历某文件夹提取特定文件名的实例
2018/04/26 Python
PyQt4 treewidget 选择改变颜色,并设置可编辑的方法
2019/06/17 Python
django admin 自定义替换change页面模板的方法
2019/08/23 Python
在Python中等距取出一个数组其中n个数的实现方式
2019/11/27 Python
Django微信小程序后台开发教程的实现
2020/06/03 Python
Python如何绘制日历图和热力图
2020/08/07 Python
python实现图片转字符画
2021/02/19 Python
css3 transform 3d 使用css3创建动态3d立方体(html5实践)
2013/01/06 HTML / CSS
HTML5之SVG 2D入门5—颜色的表示及定义方式
2013/01/30 HTML / CSS
Timberland美国官网:全球领先的户外品牌
2016/08/15 全球购物
GUESS西班牙官方网上商城:美国服饰品牌
2017/03/15 全球购物
马来西亚网上购物平台:ezbuy
2018/02/13 全球购物
维多利亚的秘密阿联酋官网:Victoria’s Secret阿联酋
2019/12/07 全球购物
C/C++有关内存的思考题
2015/12/04 面试题
普通大学毕业生自荐信
2013/11/04 职场文书
绿色小区申报材料
2014/08/22 职场文书
护士长2014年度工作总结
2014/11/11 职场文书
企业团队精神心得体会
2016/01/19 职场文书
python爬虫selenium模块详解
2021/03/30 Python