我试图调用一个接受参数start和count的API,如下所示:
function handleSuccess() {
if (!!response.data) {
return (response.data);
} else {
return q.reject(response.data);
}
}
function handleError() {
// do some handling
}
function getData(url, sortBy) {
var count = 10;
var start = 1;
var request = http({
cache: true,
method: "GET",
url: url,
params: {
sortBy: sortBy,
sortOrder: "ASC",
count: count, // e.g. 10
start: start // e.g. 1
}
});
return (request.then(handleSuccess, handleError));
}
来自API的JSON响应可能包含" next"链接,如果存在更多,将为我提供调用以获取下一组数据的URL ...这就是分页的工作方式。
最好的方法是什么,并将返回的所有数据连接到一个JSON响应中?
答案 0 :(得分:0)
假设data
响应的某些部分是一个数组,那么只需使用普通数组concat()
将其与handleSuccess()
回调中的前一页数据相结合。
答案 1 :(得分:0)
我发现,当尝试从同一端点获取分页数据时,面向服务的方式最有用,因为它很容易在控制器和指令之间共享服务和对象。
首先,我会设置你的应用程序的服务层,以便所有被请求的对象都有类似的通用方法(我强烈建议你使用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();
});
这显然是一个粗略的削减,有很大的改进空间,但我希望这将是一个很好的跳跃点,让你指向某种角度风格的方向。根据我的经验,这是从服务中的数据/请求层中抽象出分页逻辑的最佳方法。