原理和使用說明
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
