自定義angularjs分頁控件

繼昨天寫了knockoutjs+ jquery pagination+asp.net web Api 實現無刷新列表頁 ,正好最近剛學習angularjs ,故琢磨着寫一個angularjs版本的分頁控件。css

思路是自定義一個directive , 而後用isolated scope與父級controller $scope同步交互頁數和當前頁信息, 利用module的contant方法定義默認選項,從directive link 函數獲取用戶自定義選項設置。和之前寫jquery插件的思路相似, 內部定義一個默認的defaults選項,利用jQuery.extend({},defaults,userCustomOption)合併用戶自定義設置 ,而後動態構造html結構,只不過directive能夠使用模板,模板中能夠繼續使用其餘directive,因此構造html的工做能夠分配給模板來作,勞累了半天總算能夠跑起來了,勞動成果以下 angular.pagination.jshtml

;
(function(angular) {
    var myModule = angular.module("myModule", []);

    myModule.constant('pagexConfig', {
        visiblePageCount: 10,
        firstText: 'First',
        lastText: 'Last',
        prevText: 'Previous',
        nextText: 'Next'
    }).directive("pager", ['pagexConfig', function(pagexConfig) {
        return {
            link: function(scope, element, attrs) {
                var visiblePageCount = angular.isDefined(attrs.visiblePageCount) ? attrs.visiblePageCount : pagexConfig.visiblePageCount;
                scope.firstText = angular.isDefined(attrs.firstText) ? attrs.firstText : pagexConfig.firstText;
                scope.lastText = angular.isDefined(attrs.lastText) ? attrs.lastText : pagexConfig.lastText;
                scope.prevText = angular.isDefined(attrs.prevText) ? attrs.prevText : pagexConfig.prevText;
                scope.nextText = angular.isDefined(attrs.nextText) ? attrs.nextText : pagexConfig.nextText;
                scope.currentPage = 1;

                scope.pageChange = function(page) {
                    if (page >= 1 && page <= scope.pageCount) {
                        scope.currentPage = page;
                    } else {
                        scope.currentPage = 1;
                    }
                }

                function build() {
                    var low,
                        high,
                        v;

                    scope.pagenums = [];

                    if (scope.pageCount == 0) {
                        return;
                    }
                    if (scope.currentPage > scope.pageCount) {
                        scope.currentPage = 1;
                    }

                    if (scope.pageCount <= visiblePageCount) {
                        low = 1;
                        high = scope.pageCount;
                    } else {
                        v = Math.ceil(visiblePageCount / 2);
                        low = Math.max(scope.currentPage - v, 1);
                        high = Math.min(low + visiblePageCount - 1, scope.pageCount);

                        if (scope.pageCount - high < v) {
                            low = high - visiblePageCount + 1;
                        }
                    }

                    for (; low <= high; low++) {
                        scope.pagenums.push(low);
                    }

                    scope.onPageChange();
                }

                scope.$watch('currentPage+pageCount', function() {
                    build();
                });
            },
            replace: true,
            restrict: "E",
            scope: {
                pageCount: '=',
                currentPage: '=',
                onPageChange: '&'
            },
            template: '<ul class="pagination"><li ng-click="pageChange(1)">{{firstText}}</li>' +
                '<li ng-click="pageChange(currentPage-1>0?currentPage-1:1)">{{prevText}}</li>' +
                '<li ng-repeat="pagenum in pagenums" ng-click="pageChange(pagenum)" ng-class="{active:currentPage===pagenum}">{{pagenum}}</li>' +
                '<li ng-click="pageChange(currentPage+1<=pageCount?currentPage+1:pageCount)">{{nextText}}</li>' +
                '<li ng-click="pageChange(pageCount)">{{lastText}}</li></ul>'
        }
    }]);
})(angular)

簡單起見, 只定義了幾個簡單的自定義屬性, first | last | prev | next (Text) 顧名思義就是首頁,尾頁,上一頁,下一頁, visiblePageCount是用戶可見的頁碼塊。jquery

server 端代碼繼續用昨天knockoutjs 的 ,獲取頁數的稍做改變git

using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace WebApp.Api
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
    }

    public class TestController : ApiController
    {
        Product[] products = new Product[] 
        { 
            new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, 
            new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, 
            new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M },
            new Product { Id = 4, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, 
            new Product { Id = 5, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, 
            new Product { Id = 6, Name = "Hammer", Category = "Hardware", Price = 16.99M } ,
            new Product { Id = 7, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, 
            new Product { Id = 8, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, 
            new Product { Id = 9, Name = "Hammer", Category = "Hardware", Price = 16.99M },
            new Product { Id = 10, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, 
            new Product { Id = 11, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, 
            new Product { Id = 12, Name = "Hammer", Category = "Hardware", Price = 16.99M },
            new Product { Id = 13, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, 
            new Product { Id = 14, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, 
            new Product { Id = 15, Name = "Hammer", Category = "Hardware", Price = 16.99M } ,
            new Product { Id = 16, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, 
            new Product { Id = 17, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, 
            new Product { Id = 18, Name = "Hammer", Category = "Hardware", Price = 16.99M }
        };

        [Route("api/getpagecount")]
        [HttpGet]
        public int GetCount()
        {
            return products.Length % 10 == 0 ? products.Length / 10 : products.Length / 10 + 1;
        }

        [Route("api/getdata")]
        [HttpGet]
        public IEnumerable<Product> GetProduct(int pageIndex, int pageSize)
        {
            return products.Skip(pageIndex * pageSize).Take(pageSize);
        }
    }
}

view層頁碼代碼angularjs

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>index</title>
    <link href="css/style.css" rel="stylesheet" />
</head>

<body ng-app="app">
    <div ng-controller="myCtrl">
        <pager page-count="pageCount" current-page="currentPage" on-page-change="onPageChange()" first-text="首頁" last-text="最後一頁"></pager>
    </div>
    <script src="js/angular-1.2.21.min.js"></script>
    <script src="js/angular.pagination.js"></script>
    <script src="js/app.js"></script>
</body>

</html>

業務邏輯代碼github

 var app = angular.module( 'app', ['myModule'] );

        app.controller( 'myCtrl', function ( $scope, $http )
        {
            $scope.onPageChange = function ()
            {
                $http.get( '/api/getdata?pageIndex=' + ( $scope.currentPage - 1 ) + '&pageSize=10' ).success( function ( data )
                {
                    $scope.items = data;
                } );
            }

            $http.get( '/api/getpagecount' ).success( function ( data )
            {
                $scope.pageCount = data;
            } );

            $http.get( '/api/getdata?pageIndex=0&pageSize=10' ).success( function ( data )
            {
                $scope.items = data;
            } );
        } );

運行效果圖web

 純html版本的已經 發佈到github , 無須server端支持 https://github.com/leonwgc/angularjs-paginationapi

相關文章
相關標籤/搜索