学习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 相关文章推荐
Jquery AJAX 框架的使用方法
Nov 03 Javascript
按钮JS复制文本框和表格的代码
Apr 01 Javascript
最佳的addEvent事件绑定是怎样诞生的
Oct 24 Javascript
JS实现图片横向滚动效果示例代码
Sep 04 Javascript
jquery高级编程的最佳实践详解
Mar 23 Javascript
使用jquery+CSS3实现仿windows10开始菜单的下拉导航菜单特效
Sep 24 Javascript
微信小程序 WXML、WXSS 和JS介绍及详解
Oct 08 Javascript
jQuery Password Validation密码验证
Dec 30 Javascript
Javascript for in的缺陷总结
Feb 03 Javascript
微信小程序 获取二维码实例详解
Jun 23 Javascript
详解vue组件通信的三种方式
Jun 30 Javascript
JavaScript 判断数据类型的4种方法
Sep 11 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通过sort()函数给数组排序的方法
2015/03/18 PHP
php简单图像创建入门实例
2015/06/10 PHP
PHP实现原比例生成缩略图的方法
2016/02/03 PHP
laravel框架实现为 Blade 模板引擎添加新文件扩展名操作示例
2020/01/25 PHP
laravel 框架执行流程与原理简单分析
2020/02/01 PHP
出现“不能执行已释放的Script代码”错误的原因及解决办法
2007/08/29 Javascript
JavaScript 函数replace深入了解
2013/03/14 Javascript
Javascript call和apply区别及使用方法
2013/11/14 Javascript
js对字符的验证方法汇总
2015/02/04 Javascript
jQuery常用数据处理方法小结
2015/02/20 Javascript
通过Jquery.cookie.js实现展示浏览网页的历史记录超管用
2015/10/23 Javascript
JavaScript过滤字符串中的中文与空格方法汇总
2016/03/07 Javascript
JavaScript蒙板(model)功能的简单实现代码
2016/08/04 Javascript
简单理解js的prototype属性及使用
2016/12/07 Javascript
express框架实现基于Websocket建立的简易聊天室
2017/08/10 Javascript
详解VUE 数组更新
2017/12/16 Javascript
vue2.0.js的多级联动选择器实现方法
2018/02/09 Javascript
取消Bootstrap的dropdown-menu点击默认关闭事件方法
2018/08/10 Javascript
Javascript执行流程细节原理解析
2020/05/14 Javascript
JS实现简单打字测试
2020/06/24 Javascript
Python转码问题的解决方法
2008/10/07 Python
关于python的bottle框架跨域请求报错问题的处理方法
2017/03/19 Python
selenium+python实现自动登录脚本
2018/04/22 Python
对Python3.6 IDLE常用快捷键介绍
2018/07/16 Python
ActiveMQ:使用Python访问ActiveMQ的方法
2019/01/30 Python
Python完成哈夫曼树编码过程及原理详解
2019/07/29 Python
深入学习python多线程与GIL
2019/08/26 Python
python 检查数据中是否有缺失值,删除缺失值的方式
2019/12/02 Python
css3 自定义字体font-face使用介绍
2014/05/14 HTML / CSS
一个SQL面试题
2014/08/21 面试题
外贸采购员求职的自我评价
2013/11/26 职场文书
数控技术专科生自我评价
2014/01/08 职场文书
2015年团支书工作总结
2015/04/03 职场文书
2016领导干部廉洁从政心得体会
2016/01/19 职场文书
廉洁自律承诺书2016
2016/03/25 职场文书
Navicat Premium自定义 sql 标签的创建方式
2022/09/23 数据库