AngularJS实现分页功能

        对于大多数web应用来说显示项目列表是一种很常见的任务。通常情况下,我们的数据会比较多,无法很好地显示在单个页面中。在这种情况下,我们需要把数据以页的方式来展示,同时带有转到上一页和下一页的功能。既然在整个应用中这是一种很常见的需求,那么把这一功能抽象成一个通用的、可复用的分页(Paginator)服务是很有意义的。

        Paginator服务(一个很简单的实现)应该允许用户告诉它如何获取数据,可以给定offset参数、limit参数,以及每页的数据条数。然后它将会在内部处理以下逻辑:获取哪些数据?下一页是什么?是否存在下一页?等等。

        实例所提供的实现方式是:把currentPageItems字段存储在一个缓存中,如果可用的话就从这个字段里获取数据,否则就调用fetchFunction函数。当然,此服务还可以进一步扩展,实现在服务内部缓存数据。

service.js

angular.module('services', []).factory('Paginator', function() {
	//虽然这是一个服务,但是每次用户调用它时都会获得一个全新的Paginator。这是因为我们会返回一个function,当它被执行时会返回一个对象
	return function(fetchFunction, pageSize) {
		var paginator = {
			hasNextVar : false,
			next: function() {
				if(this.hasNextVar) {
					this.currentOffset += pageSize;
					this._load();
				}
			},
			_load: function() {
				var self = this;
				fetchFunction(this.currentOffset, pageSize+1, function(items) {
					self.currentPageItems = items.slice(0, pageSize);
					self.hasNextVar = items.length === pageSize + 1;
				});
			},
			hasNext: function() {
				return this.hasNextVar;
			},
			previous: function() {
				if(this.hasPrevious()) {
					this.currentOffset -= pageSize;
					this._load();
				}
			},
			hasPrevious: function() {
				return this.currentOffset !== 0;
			},currentPageItems: [],
			currentOffset:0
		};
		
		//加载第一页
		paginator._load();
		return paginator;
	};
});

        在调用Paginator服务的时候,需要两个参数:fetch函数和每一页的大小。fetch函数所期望的签名如下:

fetchFunction(offset, limit, callback);

        当Paginator需要加载并显示一个特定的页面时,就会调用此函数,同时向它传递正确的offset和limit参数。在这个函数的内部,它可以从一个很大的数组中截取数据,也可以调用服务发起一次加载数据的操作。当数据可用时,fetch函数会调用callback函数,并把数据传给它。

        Paginator暴露了它上面的currentPageItems属性,这个属性可以绑定到模板中的迭代器上(也可以使用其他展示数据的方式)。hasNext()和hasPrevious()可以用来计算何时显示Next和Previous Page链接,当点击链接时,它需要根据情况调用next()或者previous()函数。

        如果需要从服务器上加载一页数据,那么应该使用以上服务呢?以下是一种可能的控制器,它每次从服务端获取搜索之后的一页数据,示例如下:

controller.js

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

app.controller('MainCtrl', ['$scope', '$http', 'Paginator', function($scope, $http, Paginator) {
	$scope.query = 'Testing';
	var fetchFunction = function(offset, limit, callback) {
		$http.get('/search', {params:{query:$scope.query, offset: offset, limit: limit}}).success(callback);
	};
	$scope.searchPaginator = Paginator(fetchFunction, 10);
}]);

        使用Pagination服务的HTML页面如下:

index.html

<!DOCTYPE html>
<html ng-app="myApp">
<head lang="en">
	<meta charset="utf-8"></meta>
	<title>Pagination Service</title>
	<script src="angular/angular.js"></script>
	<script src="service.js"></script>
	<script src="controller.js"></script>
</head>
<body ng-controller="MainCtrl">
	<input type="text" ng-model="query"></input>
	<ul>
		<li ng-repeat="item in searchPaginator.currentPageItems">
			{{item}}
		</li>
	</ul>
	<a href="" ng-click="searchPaginator.previous()" ng-show="searchPaginator.hasPrevious()">&lt;&lt;Prev</a>
	<a href="" ng-click="searchPaginator.next()" ng-show="searchPaginator.hasNext()">Next &gt;&gt;</a>
</body>
</html>

你可能感兴趣的:(JavaScript,AngularJS,分页)