In many pages in the project, pagination is used, and each page has many duplicate pagination codes. So I wrote a simple pagination instruction to simplify the page code and be easy to maintain. I wrote it in the blog as a backup for easy access in the future.
Here are the steps to define the directive and its application:
1. Directive definition
Define a js file, page-directive.js, which is used to write paging instruction code. This file contains the paging template. The following are all the codes in the js file:
'use strict';(function () { angular.module('template/pageInit/pageInit.html', []).run([ '$templateCache',function($templateCache) { $templateCache.put('template/pageInit/pageInit.html', '<ul>/n'+ ' <li ng-class="{disabled:pageData.currentPage==1}">/n'+ ' <a href="javascript:void(0);" ng-click="on_loadPage(1)"><span></span></a>/n'+ ' <li ng-class="{disabled:pageData.currentPage==1 }">/n'+ ' <a href="javascript:void(0);" ng-click="on_prev()"><span></span></a>/n'+ ' </li>/n'+ ' <li 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 ng-class="{disabled:pageData.currentPage==pageData.totalPage}">/n'+ ' <a href="javascript:void(0);" ng-click="on_next()"><span></span></a>/n'+ ' </li>/n'+ ' <li><div><input type="text" placeholder="" ng-model="inpage">/n'+ ' <input type="button" value="jump" ng-click="on_loadPage(inpage)"></div>/n'+ ' </li>/n'+ ' <li><a href="#"><span>Total {{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. Pagination style control
It is recommended to write it in a separate .css file. First, create a new pageSync.css file. The following is the specific style.
.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: .active > a,.pagination-main > .active > span,.pagination-main > .active > a:hover,.pagination-main > .active > span:hover,.pagination-main > .active > a:focus,.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; /*pagination: 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:hover,.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. Pagination query method
I have customized the method of pagination query in factory, which is shared and convenient for code maintenance. The interaction with the background in angular is asynchronous by default. I wrote it as a synchronous query here. First, define the js file pageSync.service.js. The following is the entire content of the factory:
'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); // Get the total number of pages totalPage = Math.ceil(rows.count / pageSize); endPage = totalPage; // Generate a digital link 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; /** * Custom fields, when initialized, before. As long as the page is passed, the field value becomes after * before means that the page method has not passed, after means that the page method has passed, * Rules for loading of the foreground page: when before means that there is no data in the table, after and pataData.count==0, otherwise it is considered to have data. * It can also be said to be a time state recorded (before accessing and after returning data) */ json.loadTime = 'after'; deferred.resolve(json); }); return deferred.promise; }; // When the total number of pages is less than or equal to 7, all pages are displayed var getPagesLow = function(totalPage) { var temp = []; for (var i=1; i<totalPage+1; i++) { temp.push(i); } return temp; }; // When the total number of pages is greater than 7, get 7 page numbers based on the current page 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; }; // The height of the table in the project is calculated based on the height of the browser window and is dynamic // Because the page is to be fixed at the bottom of the table, use empty lines for no data instead of 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. Use commands
1). Code on the page:
In my code, the page is written in the tfoot in the table. Prev(), next(), and loadPage(page) are all methods defined in the corresponding controller of the page.
<table><thead> <tr> <th>Serial number</th> <th>Column name 1</th> <th>Column name 2</th> <th>Operation</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>{{row.args2}}</td> <td style="text-align: center;"><a href='#'>Modify</a></td> </tr> <tr ng-if="noTableData" ng-repeat="data in pageData.rowCollectionPage"> <td ng-if="$index == 0" colspan="4" style="text-align: center;">No data! </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> </td> </tr></tfoot></table>2).Code in controller
First, you need to reference the factory and reference PageSync in the controller, as follows:
angular.module('app').controller('MyCtrl', function(PageSync) {});
Before pagination query, you need to do some preparation:
//PageData sets the page data set, total number of pages, page number set, and total number of data. LoadTime is a custom parameter to record the time status (before accessing data and after returning data)
$scope.pageData = {rowCollectionPage: [], totalPage: 1, currentPage: 1, pages: [],count: 0, loadTime: 'before'};
// This is used to calculate the height of the table, according to the actual situation.
$scope.tabHeight = $scope.height-48-37-10-42-5;
// Calculate how many rows of data are actually on a page
$scope.pageSize = parseInt(($scope.tabHeight-15-34-34-39)/34);
Then write the following method in the controller
// Pagination query $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; } });};// Next page $scope.next = function() { if ($scope.pageData.currentPage < $scope.pageData.totalPage) { PageSync.next(url, $scope.pageData.currentPage, $scope.pageSize).then(function(data) { $scope.pageData = data; }); }};// Previous page $scope.prev = function() { if ($scope.pageData.currentPage > 1) { PageSync.prev(url, $scope.pageData.currentPage, $scope.pageSize).then(function (data) { $scope.pageData = data; }); }};// Click on the page number to jump $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('Please fill in the jump page number!'); } else if(intPage <= 0 || intPage > $scope.pageData.totalPage) { alert('The jump page number should be greater than 0, less than the total number of pages'+$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. Results
The final implementation effect is as follows:
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.