繼昨天寫了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