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>&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

时间: 2024-11-09 17:17:06

angularJS 自定义指令 分页的相关文章

angularjs自定义指令绑定策略---‘&’绑定

接着上一篇 理解了"="和"@"绑定之后再来理解"&"绑定,就很简单了,同理,用"桥梁"进行分析,但还是有一些例外的情况,要不然angularjs也不会单独设定一个绑定策略,看案例先: <!DOCTYPE html><html lang="en" ng-app="MyModule"><head>    <meta charset=&quo

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

<!doctype html> <html> <head> <meta charset="utf-8"> <title>AngularJS自定义指令与控制器数据交互</title> <!-- <script src="http://cdn.bootcss.com/angular.js/1.3.15/angular.js"></script>--> <sc

AngularJS自定义指令详解(有分页插件代码)

前言 除了 AngularJS 内置的指令外,我们还可以创建自定义指令. 通过 .directive() 函数来添加自定义的指令. 调用自定义指令时,需要在HTMl 元素上添加自定义指令名. 自定义指令命名规则:使用驼峰命名法来命名,即除第一个单词外的首字母需大写.如: myDirective. 在html页面调用该指令时需要以 - 分割,如: my-directive.示例代码: <body ng-app="myApp"> <my-directive><

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

由于最近的一个项目使用的是angularjs1.0的版本,涉及到分页查询数据的功能,后来自己就用自定义指令实现了该功能.现在单独做了个简易的小demo,主要是为了分享自己写的分页功能.注:本实例调用的是真实接口数据. 首先.小demo的目录结构如下: 一.代码部分 下面直接把每一个文件的代码贴出来,重点是ListCtrl.js和pageDirective.js: 1.index.html <!DOCTYPE html> <html lang="en" ng-app=&

【转】AngularJS——自定义指令

原文链接:http://www.html-js.com/article/1561 创建自定义指令 这是一篇译文,来自angular开发者说明的指令.主要面向已经熟悉angular开发基础的开发者.这篇文档解释了什么情况下需要创建自己的指令,和如何去创建指令. 什么是指令 从一个高的层面来讲,指令是angular $compile服务的说明,当特定的标签(属性,元素名,或者注释) 出现在DOM中的时候,它让编译器附加指定的行为到DOM上. 这个过程是很简单的.angular内部有很用这样自带的指令

AngularJS自定义指令(Directives)在IE8下的一个坑

在项目中,由于要兼容到IE8,我使用1.2.8版本的angularJS.这个版本是支持自定义指令的.我打算使用自定义指令将顶部的header从其他页面分离.也就是实现在需要header的页面只用在<body>后面加上<header></header>这个HTML标签就可以了,这样还能实现页面的语义化,而且也能在IE8中实现HTML5标签.以后很多部分都可以这一写,如搜索则可以变成<serach></serach>这样.但是在写好了后,才发现只有I

AngularJS 自定义指令详解

版权声明:本文为博主原创文章,未经博主允许不得转载. //blog.csdn.net/qq_27626333/article/details/52261409 除了 AngularJS 内置的63个指令外,我们还可以创建自定义指令.你可以使用 .directive 函数来添加自定义的指令.要调用自定义指令,HTML 元素上需要添加自定义指令名.使用驼峰法来命名一个指令, runoobDirective, 但在使用它时需要以 - 分割, runoob-directive,自定义指令的参数如下: [

angularJS自定义指令间的“沟通”

由此例子我们可以看出,angularJS使用指令时link的执行顺序<html> <head> <meta charset="utf-8"/> <title></title> </head> <body ng-app="components"> <div> <name xm> <h1>小明</h1> </name> <

AngularJs自定义指令详解(5) - link

在指令中操作DOM,我们需要link参数,这参数要求声明一个函数,称之为链接函数. 写法: link: function(scope, element, attrs) { // 在这里操作DOM} 如果指令使用了require选项,那么链接函数会有第四个参数,代表控制器或者所依赖的指令的控制器. // require 'SomeController',link: function(scope, element, attrs, SomeController) { // 在这里操作DOM,可以访问r