代码之家  ›  专栏  ›  技术社区  ›  Hasan Can Saral

如何使用带有分页的RESTfulAPI来按顺序获取AngularJS中的所有记录

  •  1
  • Hasan Can Saral  · 技术社区  · 8 年前

    我正在使用的API提供了如下链接头:

    </resource?page=1&limit=10>; rel="next",
    </resource?page=1&limit=10>; rel="last",
    </resource?page=0&limit=10>; rel="first"
    

    我需要消耗 /resource 端点,每次10个对象,在一个循环中,直到 next 在链接头(最后一页)中。

    我有这样的资源:

    myResources.factory('MyResource', [
        '$resource',
        function($resource) {
    
            const ENDPOINT = '/api/resource/:id';
    
            return $resource(ENDPOINT, null, {
                query: {
                    method: 'GET',
                    isArray: true,
                    interceptor: {
                        response: function(response) {
                            response.resource.headers = response.headers;
                            return response.resource;
                        }
                    }
                }
            });
        }]);
    

    我有这样的服务:

    myServices.factory('MyResourceService', [
        function(MyResource) {
            return {
                findResources: function(){
                    return MyResource.query().$promise;
                },
                findAllResources: function(){
                    // I need to return a promise which will fetch all 
                    // results from the server synchronously
    
                    var hasNext = true;
                    var params = {limit: 10, page: 0};
                    var chain = $q.all();
    
                    while(hasNext){
                        chain = chain.then(function(){
                            return MyResource.query(params).then(function(res){
                                var next = linkHeaderParser.parse(res.headers('link').next);
                                if(next) params = {limit: next.limit, page: next.page};
                                else hasNext = false;
                            }, function(){
                                hasNext = false;
                            });
                        });
                    }
    
                    return chain;
                },
                ...
            };
        }]);
    

    嗯,你的眼睛可能会受伤,因为我知道这不是实现这一点的正确方法,因为 hastNext 在承诺实际执行之前不会更新,这会导致无限循环。但我没办法绕过去。谢谢你的帮助。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Hasan Can Saral    8 年前

    关于 comment 通过 bigless ,我就是这样解决的:

                var getResource = function(params){
                    return MyResource
                        .query(params)
                        .$promise;
                };
    
                // Method that extracts the last page
                var pageCount = function(response){
                    var last = 
                    linkHeaderParser.parse(response.headers('link')).last;
                    return parseInt(last.page);
                };
    
                params.limit = 0;
                params.page = 0;
    
                var deferred = $q.defer();
                var resources = [];
    
                // Method that extracts the last page
                getResource(params)
                    .then(function(res){
    
                        var promises = [];
                        var lastPage = pageCount(res);
                        resources = resources.concat(res);
    
                        // Loop to get all pages
                        for(var i = params.page + 1; i <= lastPage; i++){
                            params.page = i;
                            promises.push(getResource(params));
                        }
    
                        return $q.all(promises);
                    }, function(err){
                        if(err.headers('x-pagination-count') &&
                            parseInt(err.headers('x-pagination-count')) === 0)
                            return $q.all([]);
                        }
                    })
                    .then(function(res){
    
                        // Concat results and resolve the promise
                        for (var i = 0; i < res.length; i++){
                            resources = resources.concat(res[i]);
                        }
    
                        deferred.resolve(resources);
                    });