我发现面向服务的方式在尝试从同一端点获取分页数据时最有用,因为它很容易在控制器和指令之间共享服务和对象。
首先,我将设置您的应用程序的服务层,以便所有被请求的对象都具有通用的通用方法(我强烈建议您使用 ngResource 或 RESTAngular 或类似的方法):
angular.module('myModule')
.factory('ApiObject', function($http, $q) {
ApiObject = function ApiObject(attributes) {
angular.extend(this, attributes);
};
ApiObject.query = function(url, parameters) {
var deferred = $q.defer();
$http.get(url, {params: parameters}).then(function(data) {
var results = [];
angular.forEach(data, function(apiObject) {
results.push(new ApiObject(apiObject));
});
deferred.resolve(results);
}, function(error) {
// Do error stuff
deferred.reject(error);
});
return deferred.promise;
};
return ApiObject;
});
然后设置一个服务来管理您的分页数据,该服务接受您的通用服务以及参数和配置选项。还允许在服务内触发事件(请参阅trigger 和on 方法),以便您知道何时获取新结果。我还编写了一种将结果自动连接到当前结果集的方式:
angular.module('myModule')
.factory('SearchService', function() {
SearchService = function SearchService(service, params, config) {
this.searchParams = params || {};
this.config = config || {};
this.service = service;
this.results = [];
this.listeners = {};
};
SearchService.prototype.fetch = function(params) {
var _this = this;
this.service.query().then(function(results) {
if(_this.config.concatResults) {
_this.results = _this.results.concat(results);
// You probably should make sure results are unique at this point as that is a common problem with paging a changing API
} else {
_this.results = results;
}
_this.trigger('searchSuccess', _this.results);
});
};
SearchService.prototype.on = function(event, listener) {
(this.listeners[event] = (this.listeners[event] || [])).push(listener);
};
SearchService.prototype.trigger = function(event, payload) {
angular.forEach(this.listeners[event], function(listener) {
listener(payload);
});
};
SearchService.prototype.isLastPage = function() {
//logic here to determine last page
};
SearchService.prototype.nextPage = function() {
if(this.isLastPage()) {
return;
}
if(this.searchParams.page) {
this.searchParams.page++;
} else {
this.searchParams.page = 2;
}
this.fetch();
};
// Write more methods for previousPage, lastPage, firstPage, goToPage... etc.
return SearchService;
});
然后在您的控制器中,您将要使用一些默认参数和配置来实例化搜索服务,然后获取第一页:
angular.module('myModule')
.controller('MyCtrl', function($scope, ApiObject, SearchService) {
$scope.searchService = new SearchService(ApiObject, {page: 1}, {concatResults: true});
$scope.searchService.on('searchSuccess', function(results) {
// Do something with results if you wish, but they'll already be stored in $scope.searchService
});
// Get the first page of data
$scope.searchService.fetch();
});
这显然是一个粗略的剪辑,有很大的改进空间,但我希望这将是一个很好的起点,让你指向某种角度风格的方向。根据我的经验,这是从服务中的数据/请求层抽象出分页逻辑的最佳方式。