学习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 相关文章推荐
Javascript 代码也可以变得优美的实现方法
Jun 22 Javascript
JS获取下拉列表所选中的TEXT和Value的实现代码
Jan 11 Javascript
三种检测iPhone/iPad设备方向的方法
Apr 23 Javascript
JavaScript数组函数unshift、shift、pop、push使用实例
Aug 27 Javascript
推荐阅读的js快速判断IE浏览器(兼容IE10与IE11)
Dec 13 Javascript
详解React-Todos入门例子
Nov 08 Javascript
js实现点击每个li节点,都弹出其文本值及修改
Dec 15 Javascript
详解微信小程序开发之城市选择器 城市切换
Jan 17 Javascript
Jquery uploadify 多余的Get请求(404错误)的解决方法
Jan 26 Javascript
JavaScript实现多叉树的递归遍历和非递归遍历算法操作示例
Feb 08 Javascript
浅谈vue项目可以从哪些方面进行优化
May 05 Javascript
如何从头实现一个node.js的koa框架
Jun 17 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
ucenter通信原理分析
2015/01/09 PHP
PHP使用mysql_fetch_object从查询结果中获取对象集的方法
2015/03/18 PHP
yii2 modal弹窗之ActiveForm ajax表单异步验证
2016/06/13 PHP
Display SQL Server Version Information
2007/06/21 Javascript
小议javascript 设计模式 推荐
2009/10/28 Javascript
jquery下实现overlay遮罩层代码
2010/08/25 Javascript
jquery实现奇偶行赋值不同css值
2012/02/17 Javascript
jquery遍历checkbox的注意事项说明
2014/02/21 Javascript
SeaJS入门教程系列之使用SeaJS(二)
2014/03/03 Javascript
js实现的复制兼容chrome和IE
2014/04/03 Javascript
JavaScript fontsize方法入门实例(按照指定的尺寸来显示字符串)
2014/10/17 Javascript
javascript常用功能汇总
2015/07/05 Javascript
基于jquery实现日历签到功能
2020/09/11 Javascript
JavaScript数组操作函数汇总
2016/08/05 Javascript
Angular中$cacheFactory的作用和用法实例详解
2016/08/19 Javascript
[44:01]2018DOTA2亚洲邀请赛3月30日 小组赛B组 EG VS paiN
2018/03/31 DOTA
Python yield使用方法示例
2013/12/04 Python
2款Python内存检测工具介绍和使用方法
2014/06/01 Python
Python实现从URL地址提取文件名的方法
2015/05/15 Python
举例讲解Python设计模式编程中的访问者与观察者模式
2016/01/26 Python
Python模块包中__init__.py文件功能分析
2016/06/14 Python
详解使用python crontab设置linux定时任务
2016/12/08 Python
python实现决策树C4.5算法详解(在ID3基础上改进)
2017/05/31 Python
Python实现的计数排序算法示例
2017/11/29 Python
python 3利用Dlib 19.7实现摄像头人脸检测特征点标定
2018/02/26 Python
解决Pandas to_json()中文乱码,转化为json数组的问题
2018/05/10 Python
Python之列表实现栈的工作功能
2019/01/28 Python
python实现顺时针打印矩阵
2019/03/02 Python
Python实现PyPDF2处理PDF文件的方法示例
2019/09/25 Python
PyCharm 专业版安装图文教程
2020/02/20 Python
在Python 的线程中运行协程的方法
2020/02/24 Python
python3 deque 双向队列创建与使用方法分析
2020/03/24 Python
HTML5 File接口在web页面上使用文件下载
2017/02/27 HTML / CSS
德国著名廉价网上药店:Shop-Apotheke
2017/07/23 全球购物
linux下进程间通信的方式
2014/12/23 面试题
2014市府办领导班子“四风问题”对照检查材料思想汇报
2014/09/24 职场文书