學(xué)習(xí)Angularjs分頁指令
在項目中許多頁面都用到了分頁,然后每個頁面都有許多重復(fù)的分頁代碼,于是自己寫了一份簡易的分頁指令,簡化頁面的代碼,且容易維護,寫在博客中當(dāng)做備份,方便以后查閱。
以下是定義指令及其應(yīng)用的步驟:
1.指令定義
定義一個js文件,page-directive.js,用來寫分頁的指令代碼,這個文件中包含了分頁的模板,以下是js文件中的所有代碼:
'use strict';
(function () {
angular.module('template/pageInit/pageInit.html', []).run([
'$templateCache',function($templateCache) {
$templateCache.put('template/pageInit/pageInit.html',
'<ul class="pagination-main">\n'+
' <li class="prev-page" ng-class="{disabled:pageData.currentPage==1}" title="首頁">\n'+
' <a href="javascript:void(0);" ng-click="on_loadPage(1)"><span class="fa fa-fast-backward"></span></a>\n'+
' </li>\n'+
' <li class="prev-page" ng-class="{disabled:pageData.currentPage==1 }">\n'+
' <a href="javascript:void(0);" ng-click="on_prev()" title="上一頁"><span class="fa fa-step-backward"></span></a>\n'+
' </li>\n'+
' <li class="data-page" ng-repeat="page in pageData.pages" ng-class="{\'first-page\': page==1, \'last-page\': page==pageData.totalPage}">\n'+
' <a ng-if="page!=\'...\'" href="javascript:void(0);" ng-class="{\'bg-custom\': page==pageData.currentPage}" ng-click="on_loadPage(page, tabData)">{{ page }}</a>\n'+
' <a ng-if="page==\'...\'" href="javascript:void(0);" ng-class="{\'bg-custom\': page==pageData.currentPage}" ng-click="">{{ page }}</a>\n'+
' </li>\n'+
' <li class="next-page" ng-class="{disabled:pageData.currentPage==pageData.totalPage}">\n'+
' <a href="javascript:void(0);" ng-click="on_next()" title="下一頁"><span class="fa fa-step-forward"></span></a>\n'+
' </li>\n'+
' <li class="skip-page"><div><input type="text" placeholder="" ng-model="inpage">\n'+
' <input type="button" value="跳轉(zhuǎn)" ng-click="on_loadPage(inpage)"></div>\n'+
' </li>\n'+
' <li class="data-num"><a class="cursor-text" href="#"><span>共{{pageData.count}}條</span></a></li>\n'+
'</ul>\n'+
''
);
}
]);
angular.module('pageInit', ['template/pageInit/pageInit.html'])
.directive('pageInit',['pageinitTemplate', function(pageinitTemplate) {
return {
restrict : 'AE',
templateUrl: function (tElement, tAttrs) {
return tAttrs.templateUrl || pageinitTemplate.getPath();
},
replace : true,
scope : {
pageData : '=',
prev : '&',
next : '&',
loadPage : '&'
},
link : function(scope, element, attrs) {
scope.on_prev = function() {
if(scope.prev) {
scope.prev();
}
};
scope.on_next = function() {
if(scope.next) {
scope.next();
}
};
scope.on_loadPage = function(page) {
scope.inpage = undefined;
if(scope.loadPage) {
scope.loadPage({page: page});
}
};
}
};
}])
.provider('pageinitTemplate', function () {
var templatePath = 'template/pageInit/pageInit.html';
this.setPath = function (path) {
templatePath = path;
};
this.$get = function () {
return {
getPath: function () {
return templatePath;
}
};
};
});
}).call(window);
2.分頁樣式控制
建議寫在單獨的.css文件中,首先新建pageSync.css文件,以下是具體樣式
.pagination-main {
display: inline-block;
padding-left: 0;
margin: 0 0;
border-radius: 4px;
vertical-align: middle;
}
.pagination-main li.prev-page > a {
border: 0;
}
.pagination-main li.next-page > a {
border: 0;
border-left: 1px;
margin-left: 0;
}
.pagination-main li.first-page > a {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.pagination-main li.last-page > a {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.pagination-main li div {
width: 80px;border: 1px solid #DDDDDD;background-color: #ffffff;float: left;padding: 0;
}
.pagination-main li.skip-page input[type='text'] {
width: 24px;height: 20px;border: 0;text-align: center;
}
.pagination-main li.skip-page input[type='button'] {
padding: 0 4px 1px 10px;border: 0;border-left: 1px solid #dddddd;background-color: #ffffff
}
.pagination-main li.data-num > a {
border: 0;
margin-left: 0;
}
.pagination-main > li {
display: inline;
}
.pagination-main > li:first-child > a,
.pagination-main > li:first-child > span {
/*margin-left: 0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;*/
}
.pagination-main > .active > a,
.pagination-main > .active > span,
.pagination-main > .active > a:hover,
.pagination-main > .active > span:hover,
.pagination-main > .active > a:focus,
.pagination-main > .active > span:focus {
z-index: 2;
color: #fff;
cursor: default;
background-color: #428bca;
border-color: #428bca;
}
.pagination-main > li > a,
.pagination-main > li > span {
position: relative;
float: left;
/*padding: 6px 12px;*/
padding: 1px 8px;
margin-left: -1px;
line-height: 1.42857143;
color: #428bca;
text-decoration: none;
background-color: #fff;
border: 1px solid #ddd;
}
.pagination-main > .disabled > span,
.pagination-main > .disabled > span:hover,
.pagination-main > .disabled > span:focus,
.pagination-main > .disabled > a,
.pagination-main > .disabled > a:hover,
.pagination-main > .disabled > a:focus {
color: #999;
cursor: not-allowed;
background-color: #fff;
border-color: #ddd;
}
3.分頁查詢方法
我在factory中自定義了分頁查詢的方法,共用,方便代碼的維護。在angular中與后臺的交互默認(rèn)是異步的,我這里寫成同步查詢了,首先定義js文件pageSync.service.js,以下是factory的全部內(nèi)容:
'use strict';
angular.module('app').factory('PageSync', ['$http', '$q', function Page($http, $q) {
var rowCollectionPage = [];
var totalPage = 1;
var pages = [];
var endPage = 1;
var load = function(url, currentPage, pageSize,deferred) {
var json = {rowCollectionPage: [], totalPage: 1, currentPage:currentPage ? currentPage:1, pages: []};
$http.get(url).success(function(rows) {
rowCollectionPage = setPageRow(rows.list, pageSize);
// 獲取總頁數(shù)
totalPage = Math.ceil(rows.count / pageSize);
endPage = totalPage;
// 生成數(shù)字鏈接
if (totalPage <= 7) {
pages = getPagesLow(totalPage);
} else {
pages = getPagesHigh(currentPage, totalPage);
}
json.rowCollectionPage = rowCollectionPage;
json.totalPage = totalPage==0 ? 1 : totalPage;
json.currentPage = currentPage;
json.pages = pages;
json.count = rows.count;
json.pageSize = pageSize;
/**
* 自定義字段,初始化的時候為before,只要經(jīng)過該分頁方法,則字段值變?yōu)閍fter
* before表示未經(jīng)過該分頁方法,after表示經(jīng)過該分頁方法,
* 前臺頁面加載的規(guī)則:為before時表示表格無數(shù)據(jù),為after且pataData.count==0時無數(shù)據(jù),否則視為有數(shù)據(jù),
* 也可以說是記錄的一個時間狀態(tài)(訪問數(shù)據(jù)前及返回數(shù)據(jù)后)
*/
json.loadTime = 'after';
deferred.resolve(json);
});
return deferred.promise;
};
// 總頁數(shù)小于等于7時 顯示所有的頁數(shù)
var getPagesLow = function(totalPage) {
var temp = [];
for (var i=1; i<totalPage+1; i++) {
temp.push(i);
}
return temp;
};
// 總頁數(shù)大于7時 根據(jù)當(dāng)前頁獲取7個頁碼數(shù)
var getPagesHigh = function(currentPage, totalPage) {
var temp = [];
if (currentPage < 4) {
temp = [1, 2, 3, 4, 5, '...', totalPage];
} else if ((totalPage - currentPage) <= 3) {
temp = [
totalPage - 6, totalPage - 5, totalPage - 4,
totalPage - 3, totalPage - 2, totalPage - 1, totalPage
];
} else {
temp = [
currentPage - 2, currentPage - 1, currentPage,
currentPage + 1, currentPage + 2, '...', totalPage
];
}
return temp;
};
// 項目中table的高度是根據(jù)瀏覽器窗口的高度計算的來的,是動態(tài)的
// 因為要把分頁固定在table最下方,所以無數(shù)據(jù)的用空行進行代替
var setPageRow = function(rowArr, pageSize) {
var temp = [];
if (rowArr != undefined) {
for (var i = 0; i < rowArr.length; i++) {
temp.push(rowArr[i]);
}
for (var j = 0; j < pageSize - rowArr.length; j++) {
temp.push({});
}
} else {
for (var k = 0; k < pageSize; k++) {
temp.push({});
}
}
return temp;
};
return {
load: function(url, currentPage, pageSize) {
var deferred = $q.defer();
url += '&' + currentPage + '&' + pageSize;
return load(url, currentPage, pageSize, deferred);
},
next: function(url, currentPage, pageSize) {
var deferred = $q.defer();
if (currentPage < endPage) {
currentPage++;
}
url += '&' + currentPage + '&' + pageSize;
return load(url, currentPage, pageSize, deferred);
},
prev: function(url, currentPage, pageSize) {
var deferred = $q.defer();
currentPage--;
url += '&' + currentPage + '&' + pageSize;
return load(url, currentPage, pageSize, deferred);
},
loadPage: function(url, currentPage, pageSize, page) {
var deferred = $q.defer();
if (currentPage != page) {
currentPage = page;
url += '&' + currentPage + '&' + pageSize;
return load(url, currentPage, pageSize, deferred);
}
}
}
}]);
4.使用指令
1).頁面上的代碼:
我的代碼中分頁是寫在table中的tfoot里面了,prev()、next()、loadPage(page)均為在頁面對應(yīng)的controller中定義的方法
<table>
<thead>
<tr>
<th>序號</th>
<th>列名1</th>
<th>列名2</th>
<th style="width: 150px;text-align: center;">操作</th>
</tr>
</thead>
<tbody>
<tr ng-if="!noTableData" ng-repeat="row in pageData.rowCollectionPage">
<td>{{!!row.id ? $index+1+(pageData.currentPage-1)*pageSize : ''}}</td>
<td>{{row.args1}}</td>
<td>{{row.args2}}</td>
<td style="text-align: center;"><a href='#'>修改</a></td>
</tr>
<tr ng-if="noTableData" ng-repeat="data in pageData.rowCollectionPage">
<td ng-if="$index == 0" colspan="4" style="text-align: center;">沒有數(shù)據(jù)!</td>
<td ng-if="$index != 0" colspan="4"></td>
</tr>
</tbody>
<tfoot>
<tr>
<td style="text-align: center;" colspan="6">
<div>
<page-init page-data="pageData" prev="prev()" next="next()" load-page="loadPage(page)"></page-init>
</div>
</td>
</tr>
</tfoot>
</table>
2).controller中的代碼
首先要引用factory,將PageSync在controller中引用,如下:
angular.module('app').controller('MyCtrl', function(PageSync) {});
在分頁查詢之前要做一些準(zhǔn)備工作:
//pageData中設(shè)置分頁數(shù)據(jù)集合、總頁數(shù)、頁碼集合、數(shù)據(jù)總數(shù),loadTime為自定義的參數(shù),用來記錄時間狀態(tài)(訪問數(shù)據(jù)前及返回數(shù)據(jù)后)
$scope.pageData = {rowCollectionPage: [], totalPage: 1, currentPage:1, pages: [],count: 0, loadTime: 'before'};
// 這里用來計算table的高度,根據(jù)實際情況來。
$scope.tabHeight = $scope.height-48-37-10-42-5;
// 計算實際中一頁有多少行數(shù)據(jù)
$scope.pageSize = parseInt(($scope.tabHeight-15-34-34-39)/34);
然后再controller中寫如下的方法
// 分頁查詢
$scope.load = function(row) {
$scope.surgeonPageData.rowCollectionPage = Common.setPageRow([],$scope.pageSize);
$scope.noSurgeonData = false;
$scope.surgeonPageData.loadTime = 'before';
PageSync.load(url, $scope.pageData.currentPage, $scope.pageSize).then(function(data) {
$scope.pageData = data;
if(($scope.pageData.loadTime=='after'&& $scope.pageData.count==0) || $scope.pageData.loadTime=='before') {
$scope.noTableData = true;
}
});
};
// 下一頁
$scope.next = function() {
if ($scope.pageData.currentPage < $scope.pageData.totalPage) {
PageSync.next(url, $scope.pageData.currentPage, $scope.pageSize).then(function(data) {
$scope.pageData = data;
});
}
};
// 上一頁
$scope.prev = function() {
if ($scope.pageData.currentPage > 1) {
PageSync.prev(url, $scope.pageData.currentPage, $scope.pageSize).then(function (data) {
$scope.pageData = data;
});
}
};
// 點擊頁碼跳轉(zhuǎn)
$scope.loadPage = function(page) {
$scope.inpage = undefined;
var intPage;
if (typeof page == 'string') {
if(page!="") {
intPage = parseInt(page, 10);
} else {
intPage = 0;
}
} else {
intPage = page;
}
if ($scope.pageData.totalPage <= 1) {
} else if (intPage == undefined || intPage == null) {
alert('請?zhí)顚懱D(zhuǎn)頁碼!');
} else if(intPage <= 0 || intPage > $scope.pageData.totalPage) {
alert('跳轉(zhuǎn)頁碼應(yīng)大于0,小于總頁數(shù)'+$scope.pageData.totalPage);
} else if ($scope.pageData.currentPage != page) {
PageSync.loadPage(url, $scope.pageData.currentPage, $scope.pageSize, page).then(function (data) {
$scope.pageData = data;
});
}
};
5.結(jié)果
最終的實現(xiàn)效果如下圖:


以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
angularjs循環(huán)對象屬性實現(xiàn)動態(tài)列的思路詳解
這篇文章主要介紹了angularjs循環(huán)對象屬性實現(xiàn)動態(tài)列的思路詳解,本文給大家分享一個demo代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-11-11
使用 Github Actions 自動部署 Angular 應(yīng)用到 Github Pages的方法
這篇文章主要介紹了使用 Github Actions 自動部署 Angular 應(yīng)用到 Github Pages,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07
使用AngularJS編寫較為優(yōu)美的JavaScript代碼指南
這篇文章主要介紹了使用AngularJS編寫較為優(yōu)美的JavaScript代碼指南,包括控制器和封裝等進階技巧上的編程建議,傾力推薦!需要的朋友可以參考下2015-06-06
AngularJS之ionic 框架下實現(xiàn) Localstorage本地存儲
這篇文章主要介紹了AngularJS之ionic 框架下實現(xiàn) Localstorage本地存儲,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04
詳解AngularJS中$filter過濾器使用(自定義過濾器)
這篇文章主要介紹了詳解AngularJS中$filter過濾器使用(自定義過濾器)的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02
詳解Angular中實現(xiàn)自定義組件的雙向綁定的兩種方法
這篇文章主要介紹了詳解Angular中實現(xiàn)自定義組件的雙向綁定的兩種方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11

