angularJS 自定义指令 分页
原理和使用说明
1、插件源码主要基于angular directive来实现。
2、调用时关键地方是后台请求处理函数,也就是从后台取数据。
3、插件有两个关键参数currentPage、itemsPerPage,当前页码和每页的记录数。
4、实现方法调用后我们需要根据每次点击分页插件页码时重新提交后台来获取相应页码数据。 在调用的页码中我使用了$watch来监控。 我初次使用时是把调用函数放在了插件的onchange中,结果发现每次都会触发两次后台。这个地方需要注意。
5、我把请求后台封装成了Service层,然后在Controller里调用,也符合MVC思想。
效果图
调用代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
<div ng-app= "DemoApp" ng-controller= "DemoController" > <table class = "table table-striped" > <thead> <tr> <td>ID</td> <td>FirstName</td> <td>LastName</td> <td>Status</td> <td>Address</td> </tr> </thead> <tbody> <tr ng-repeat= "emp in persons" > <td>{{emp.ID}}</td> <td>{{emp.FirstName}}</td> <td>{{emp.LastName}}</td> <td>{{emp.Status}}</td> <td>{{emp.Address}}</td> </tr> </tbody> </table> <tm-pagination conf= "paginationConf" ></tm-pagination> </div> <script type= "text/javascript" > var app = angular.module( 'DemoApp' , [ 'tm.pagination' ]); app.controller( 'DemoController' , [ '$scope' , 'BusinessService' , function ($scope, BusinessService) { var GetAllEmployee = function () { var postData = { pageIndex: $scope.paginationConf.currentPage, pageSize: $scope.paginationConf.itemsPerPage } BusinessService.list(postData).success( function (response) { $scope.paginationConf.totalItems = response.count; $scope.persons = response.items; }); } //配置分页基本参数 $scope.paginationConf = { currentPage: 1, itemsPerPage: 5 }; /*************************************************************** 当页码和页面记录数发生变化时监控后台查询 如果把currentPage和itemsPerPage分开监控的话则会触发两次后台事件。 ***************************************************************/ $scope.$watch( 'paginationConf.currentPage + paginationConf.itemsPerPage' , GetAllEmployee); }]); //业务类 app.factory( 'BusinessService' , [ '$http' , function ($http) { var list = function (postData) { return $http.post( '/Employee/GetAllEmployee' , postData); } return { list: function (postData) { return list(postData); } } }]); </script> |
directive:
.directive('tmPagination',[function(){
return {
restrict: 'EA',
template: '<div class="page-list">' +
'<ul class="pagination" ng-show="conf.totalItems > 0">' +
'<li ng-class="{disabled: conf.currentPage == 1}" ng-click="prevPage()"><span>«</span></li>' +
'<li ng-repeat="item in pageList track by $index" ng-class="{active: item == conf.currentPage, separate: item == \'...\'}" ' +
'ng-click="changeCurrentPage(item)">' +
'<span>{{ item }}</span>' +
'</li>' +
'<li ng-class="{disabled: conf.currentPage == conf.numberOfPages}" ng-click="nextPage()"><span>»</span></li>' +
'</ul>' +
'<div class="page-total" ng-show="conf.totalItems > 0">' +
'第<input type="text" ng-model="jumpPageNum" ng-keyup="jumpToPage($event)"/>页 ' +
'每页<select ng-model="conf.itemsPerPage" ng-options="option for option in conf.perPageOptions " ng-change="changeItemsPerPage()"></select>' +
'/共<strong>{{ conf.totalItems }}</strong>条' +
'</div>' +
'<div class="no-items" ng-show="conf.totalItems <= 0">暂无数据</div>' +
'</div>',
replace: true,
scope: {
conf: '='
},
link: function(scope, element, attrs){ // 变更当前页
scope.changeCurrentPage = function(item){
if(item == '...'){
return;
}else{
scope.conf.currentPage = item;
}
}; // 定义分页的长度必须为奇数 (default:9)
scope.conf.pagesLength = parseInt(scope.conf.pagesLength) ? parseInt(scope.conf.pagesLength) : 9 ;
if(scope.conf.pagesLength % 2 === 0){
// 如果不是奇数的时候处理一下
scope.conf.pagesLength = scope.conf.pagesLength -1;
} // conf.erPageOptions
if(!scope.conf.perPageOptions){
scope.conf.perPageOptions = [10, 15, 20, 30, 50];
} // pageList数组
function getPagination(){
// conf.currentPage
scope.conf.currentPage = parseInt(scope.conf.currentPage) ? parseInt(scope.conf.currentPage) : 1;
// conf.totalItems
scope.conf.totalItems = parseInt(scope.conf.totalItems); // conf.itemsPerPage (default:15)
// 先判断一下本地存储中有没有这个值
if(scope.conf.rememberPerPage){
if(!parseInt(localStorage[scope.conf.rememberPerPage])){
localStorage[scope.conf.rememberPerPage] = parseInt(scope.conf.itemsPerPage) ? parseInt(scope.conf.itemsPerPage) : 15;
} scope.conf.itemsPerPage = parseInt(localStorage[scope.conf.rememberPerPage]); }else{
scope.conf.itemsPerPage = parseInt(scope.conf.itemsPerPage) ? parseInt(scope.conf.itemsPerPage) : 15;
} // numberOfPages
scope.conf.numberOfPages = Math.ceil(scope.conf.totalItems/scope.conf.itemsPerPage); // judge currentPage > scope.numberOfPages
if(scope.conf.currentPage < 1){
scope.conf.currentPage = 1;
} if(scope.conf.currentPage > scope.conf.numberOfPages){
scope.conf.currentPage = scope.conf.numberOfPages;
} // jumpPageNum
scope.jumpPageNum = scope.conf.currentPage; // 如果itemsPerPage在不在perPageOptions数组中,就把itemsPerPage加入这个数组中
var perPageOptionsLength = scope.conf.perPageOptions.length;
// 定义状态
var perPageOptionsStatus;
for(var i = 0; i < perPageOptionsLength; i++){
if(scope.conf.perPageOptions[i] == scope.conf.itemsPerPage){
perPageOptionsStatus = true;
}
}
// 如果itemsPerPage在不在perPageOptions数组中,就把itemsPerPage加入这个数组中
if(!perPageOptionsStatus){
scope.conf.perPageOptions.push(scope.conf.itemsPerPage);
} // 对选项进行sort
scope.conf.perPageOptions.sort(function(a, b){return a-b}); scope.pageList = [];
if(scope.conf.numberOfPages <= scope.conf.pagesLength){
// 判断总页数如果小于等于分页的长度,若小于则直接显示
for(i =1; i <= scope.conf.numberOfPages; i++){
scope.pageList.push(i);
}
}else{
// 总页数大于分页长度(此时分为三种情况:1.左边没有...2.右边没有...3.左右都有...)
// 计算中心偏移量
var offset = (scope.conf.pagesLength - 1)/2;
if(scope.conf.currentPage <= offset){
// 左边没有...
for(i =1; i <= offset +1; i++){
scope.pageList.push(i);
}
scope.pageList.push('...');
scope.pageList.push(scope.conf.numberOfPages);
}else if(scope.conf.currentPage > scope.conf.numberOfPages - offset){
scope.pageList.push(1);
scope.pageList.push('...');
for(i = offset + 1; i >= 1; i--){
scope.pageList.push(scope.conf.numberOfPages - i);
}
scope.pageList.push(scope.conf.numberOfPages);
}else{
// 最后一种情况,两边都有...
scope.pageList.push(1);
scope.pageList.push('...'); for(i = Math.ceil(offset/2) ; i >= 1; i--){
scope.pageList.push(scope.conf.currentPage - i);
}
scope.pageList.push(scope.conf.currentPage);
for(i = 1; i <= offset/2; i++){
scope.pageList.push(scope.conf.currentPage + i);
} scope.pageList.push('...');
scope.pageList.push(scope.conf.numberOfPages);
}
} if(scope.conf.onChange){
scope.conf.onChange();
}
scope.$parent.conf = scope.conf;
} // prevPage
scope.prevPage = function(){
if(scope.conf.currentPage > 1){
scope.conf.currentPage -= 1;
}
};
// nextPage
scope.nextPage = function(){
if(scope.conf.currentPage < scope.conf.numberOfPages){
scope.conf.currentPage += 1;
}
}; // 跳转页
scope.jumpToPage = function(){
scope.jumpPageNum = scope.jumpPageNum.replace(/[^0-9]/g,'');
if(scope.jumpPageNum !== ''){
scope.conf.currentPage = scope.jumpPageNum;
}
}; // 修改每页显示的条数
scope.changeItemsPerPage = function(){
// 清除本地存储的值方便重新设置
if(scope.conf.rememberPerPage){
localStorage.removeItem(scope.conf.rememberPerPage);
}
}; scope.$watch(function(){
var newValue = scope.conf.currentPage + ' ' + scope.conf.totalItems + ' ';
// 如果直接watch perPage变化的时候,因为记住功能的原因,所以一开始可能调用两次。
//所以用了如下方式处理
if(scope.conf.rememberPerPage){
// 由于记住的时候需要特别处理一下,不然可能造成反复请求
// 之所以不监控localStorage[scope.conf.rememberPerPage]是因为在删除的时候会undefind
// 然后又一次请求
if(localStorage[scope.conf.rememberPerPage]){
newValue += localStorage[scope.conf.rememberPerPage];
}else{
newValue += scope.conf.itemsPerPage;
}
}else{
newValue += scope.conf.itemsPerPage;
}
return newValue; }, getPagination); }
};
}]);
插件和Demo下载
http://yunpan.cn/cQEhnLrpnkniQ 访问密码 be74
angularJS 自定义指令 分页的更多相关文章
- AngularJs自定义指令详解(1) - restrict
下面所有例子都使用angular-1.3.16.下载地址:http://cdn.bootcss.com/angular.js/1.3.16/angular.min.js 既然AngularJs快要发布 ...
- AngularJS: 自定义指令与控制器数据交互
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- 浅析AngularJS自定义指令之嵌入(transclude)
AngularJS自定义指令的嵌入功能与vue的插槽十分类似,都可以实现一些自定义内容展现.在开始之前先简单介绍下自定义指令的transclude属性和AngularJS的内置指令ng-transcl ...
- angularjs自定义指令Directive
今天学习angularjs自定义指令Directive.Directive是一个非常棒的功能.可以实现我们自义的的功能方法. 下面的例子是演示用户在文本框输入的帐号是否为管理员的帐号"Adm ...
- angularJs 自定义指令传值---父级与子级之间的通信
angularJs自定义指令用法我忽略,之前有写过,这里只说一下父子级之间如何传值: 例如: 模块我定义为myApp,index.html定义 <my-html bol-val="bo ...
- angularjs自定义指令实现分页插件
由于最近的一个项目使用的是angularjs1.0的版本,涉及到分页查询数据的功能,后来自己就用自定义指令实现了该功能.现在单独做了个简易的小demo,主要是为了分享自己写的分页功能.注:本实例调用的 ...
- AngularJs自定义指令详解(6) - controller、require
在前面文章中提到一旦声明了require,则链接函数具有第四个参数:controller. 可见require和controller是配合使用的. 在自定义指令中使用controller,目的往往是要 ...
- angularJs自定义指令.directive==类似自定义标签
创建自定义的指令 除了 AngularJS 内置的指令外,我们还可以创建自定义指令. 你可以使用 .directive 函数来添加自定义的指令. 要调用自定义指令,HTML 元素上需要添加自定义指令名 ...
- angularJS——自定义指令
主要介绍指令定义的选项配置 //angular指令的定义,myDirective ,使用驼峰命名法 angular.module('myApp', []) .directive('myDirectiv ...
随机推荐
- [luoguP2765] 魔术球问题(最大流—最小不相交路径覆盖)
传送门 枚举球的个数 num 如果 i < j && (i + j) 是完全平方数,那么 i -> j' 连一条边 再加一个超级源点 s,s -> i 再加一个超级汇 ...
- webpack错误Chunk.entry was removed. Use hasRuntime()
这个错误在从webpack1升级webpack2或webpack3时候都遇到了,起初查到的都是extract-text-webpack-plugin版本的问题,升级了还是不管用.搜索引擎上查不到其他的 ...
- flex宽度总结
flex宽度相关的属性有三个 flex-grow,flex-shrink,flex-basis.下面分别介绍其相关特点: flex-grow 扩大因子,主轴有剩余空间时,元素分配到剩余空间的比率 fl ...
- Zygote原理学习
1 zygote分析 1.1 简介 Zygote本身是一个NATIVE层的应用程序,与驱动.内核无关.前面已经介绍过了,zygote由init进程根据init.rc配置文件创建.其实本质上来说,zyg ...
- d3 数据绑定
绑定过程 选择元素,绑定数据,追加元素 <!DOCTYPE html> <html> <head> <title>testD3-.html</ti ...
- 使用UE配置Python编程环境
一直在使用UE来进行python编程,觉得在UE下进行python编程使用起来还是很方便地,现在特来总结一下: 1.首先是python环境搭建 (1)下载python2.7 https://www.p ...
- vs nuget package control.
关于nuget,貌似使用nuget获取的package会在项目解决方案根目录下面将所有download下来的依赖包存储下来,所以这里的package会是最后所有的引用所在,既然不自己维护dll库的位置 ...
- ML| EM
What's xxx The EM algorithm is used to find the maximum likelihood parameters of a statistical model ...
- vim可视化&Linux系统安全最小化原则& su & sudo
一.vim在可视化模式下编辑 crl+v,会变成-- VISUAL BLOCK --,然后用上下左右键去选中. 多行注释: ESC进入命令行模式; Ctrl+v进入VISUAL BLOCK模式 上下左 ...
- HDU4372 Buildings
@(HDU)[Stirling數, 排列組合] Problem Description There are N buildings standing in a straight line in the ...