原理和使用说明

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>&laquo;</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>&raquo;</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 自定义指令 分页的更多相关文章

  1. AngularJs自定义指令详解(1) - restrict

    下面所有例子都使用angular-1.3.16.下载地址:http://cdn.bootcss.com/angular.js/1.3.16/angular.min.js 既然AngularJs快要发布 ...

  2. AngularJS: 自定义指令与控制器数据交互

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  3. 浅析AngularJS自定义指令之嵌入(transclude)

    AngularJS自定义指令的嵌入功能与vue的插槽十分类似,都可以实现一些自定义内容展现.在开始之前先简单介绍下自定义指令的transclude属性和AngularJS的内置指令ng-transcl ...

  4. angularjs自定义指令Directive

    今天学习angularjs自定义指令Directive.Directive是一个非常棒的功能.可以实现我们自义的的功能方法. 下面的例子是演示用户在文本框输入的帐号是否为管理员的帐号"Adm ...

  5. angularJs 自定义指令传值---父级与子级之间的通信

    angularJs自定义指令用法我忽略,之前有写过,这里只说一下父子级之间如何传值: 例如: 模块我定义为myApp,index.html定义 <my-html bol-val="bo ...

  6. angularjs自定义指令实现分页插件

    由于最近的一个项目使用的是angularjs1.0的版本,涉及到分页查询数据的功能,后来自己就用自定义指令实现了该功能.现在单独做了个简易的小demo,主要是为了分享自己写的分页功能.注:本实例调用的 ...

  7. AngularJs自定义指令详解(6) - controller、require

    在前面文章中提到一旦声明了require,则链接函数具有第四个参数:controller. 可见require和controller是配合使用的. 在自定义指令中使用controller,目的往往是要 ...

  8. angularJs自定义指令.directive==类似自定义标签

    创建自定义的指令 除了 AngularJS 内置的指令外,我们还可以创建自定义指令. 你可以使用 .directive 函数来添加自定义的指令. 要调用自定义指令,HTML 元素上需要添加自定义指令名 ...

  9. angularJS——自定义指令

    主要介绍指令定义的选项配置 //angular指令的定义,myDirective ,使用驼峰命名法 angular.module('myApp', []) .directive('myDirectiv ...

随机推荐

  1. 用-webkit-box-reflect制作倒影

    1.只在webkit内核的浏览器上有效果 2.语法: -webkit-box-reflect: <direction> <offset> <mask-box-image& ...

  2. Codeforces Round #345 (Div. 2)——B. Beautiful Paintings(贪心求上升序列个数)

    B. Beautiful Paintings time limit per test 1 second memory limit per test 256 megabytes input standa ...

  3. BZOJ-1036 [ZJOI2008]树的统计

    树链剖分模版题. #include <cstdlib> #include <cstdio> #include <cstring> #include <algo ...

  4. mysql 查询死锁语句

    我们可以用下面三张表来查原因:        innodb_trx ## 当前运行的所有事务        innodb_locks ## 当前出现的锁        innodb_lock_wait ...

  5. java 自定义log类

    目录机构如下: package tpf.common; import org.apache.log4j.*; import java.io.File; import java.net.URL; pub ...

  6. FOJ Problem 2261 浪里个浪

                                                                                                        ...

  7. 标准C程序设计七---56

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  8. 标准C程序设计七---45

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  9. UVA - 10196:Check The Check

    类型:简单模拟 大致题意:已知国际象棋行棋规则,给你一个局面,问是否将军?谁将谁的军?(保证不会同时将军) 思路:都以小写字母 测试 是否将 大写字母. 然后一个局面测两次(一次直接测,一次反转棋盘, ...

  10. Codeforces 804D Expected diameter of a tree(树的直径 + 二分 + map查询)

    题目链接 Expected diameter of a tree 题目意思就是给出一片森林, 若把任意两棵树合并(合并方法为在两个树上各自任选一点然后连一条新的边) 求这棵新的树的树的直径的期望长度. ...