学习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 相关文章推荐
动态加载js文件 document.createElement
Oct 14 Javascript
js实现右下角可关闭最小化div(可用于展示推荐内容)
Jun 24 Javascript
分享Javascript中最常用的55个经典小技巧
Nov 29 Javascript
jQuery实现弹出窗口中切换登录与注册表单
Jun 05 Javascript
AngularJS中watch监听用法分析
Nov 04 Javascript
vue + socket.io实现一个简易聊天室示例代码
Mar 06 Javascript
vue中element-ui表格缩略图悬浮放大功能的实例代码
Jun 26 Javascript
ES6 系列之 WeakMap的使用示例
Aug 06 Javascript
layer.open关闭父窗口 以及调用父页面的方法
Aug 17 Javascript
layui 实现二级弹窗弹出之后 关闭一级弹窗的方法
Sep 18 Javascript
JavaScript oncopy事件用法实例解析
May 13 Javascript
vue动态设置路由权限的主要思路
Jan 13 Vue.js
仿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用mb_string函数库处理与windows相关中文字符及Win环境下开启PHP Mb_String方法
2015/11/11 PHP
php curl 模拟登录并获取数据实例详解
2016/12/22 PHP
js 链式延迟执行DOME
2012/01/04 Javascript
12种不宜使用的Javascript语法整理
2013/11/04 Javascript
js使用eval解析json(js中使用json)
2014/01/17 Javascript
js实现div的切换特效上一个下一个
2014/02/11 Javascript
一个html5播放视频的video控件只支持android的默认格式mp4和3gp
2014/05/08 Javascript
kindeditor修复会替换script内容的问题
2015/04/03 Javascript
HTML+CSS+JS实现完美兼容各大浏览器的TABLE固定列
2015/04/26 Javascript
JavaScript返回上一页的三种方法及区别介绍
2015/07/04 Javascript
jQuery插件Timelinr 实现时间轴特效
2015/10/04 Javascript
js基础之DOM中元素对象的属性方法详解
2016/10/28 Javascript
Angular5整合富文本编辑器TinyMCE的方法(汉化+上传)
2020/05/26 Javascript
prettier自动格式化去换行的实现代码
2020/08/25 Javascript
python模拟登录百度代码分享(获取百度贴吧等级)
2013/12/27 Python
python获取网页状态码示例
2014/03/30 Python
使用Python编写一个在Linux下实现截图分享的脚本的教程
2015/04/24 Python
Python中处理字符串之endswith()方法的使用简介
2015/05/18 Python
Python爬虫实例_利用百度地图API批量获取城市所有的POI点
2018/01/10 Python
python 对txt中每行内容进行批量替换的方法
2018/07/11 Python
pandas进行时间数据的转换和计算时间差并提取年月日
2019/07/06 Python
python 图片去噪的方法示例
2019/07/09 Python
基于Python获取照片的GPS位置信息
2020/01/20 Python
python对数组进行排序,并输出排序后对应的索引值方式
2020/02/28 Python
django 链接多个数据库 并使用原生sql实现
2020/03/28 Python
Windows下Anaconda安装、换源与更新的方法
2020/04/17 Python
opencv 实现特定颜色线条提取与定位操作
2020/06/02 Python
python 基于opencv去除图片阴影
2021/01/26 Python
在PyCharm中安装PaddlePaddle的方法
2021/02/05 Python
eBay加拿大站:eBay.ca
2019/06/20 全球购物
医科学校毕业生自荐信
2013/11/09 职场文书
业务员自荐信范文
2014/04/20 职场文书
学校学习型党组织建设心得体会
2019/06/21 职场文书
ElementUI实现el-form表单重置功能按钮
2021/07/21 Javascript
「租借女友」第2季樱泽墨角色PV&新视觉图公开
2022/03/21 日漫
Vertica集成Apache Hudi重磅使用指南
2022/03/31 Servers