如何处理分页,并与angularjs资源算什么?(How to handle pagination

2019-09-02 10:04发布

我必须建立一个angularjs客户端的API输出JSON是这样的:

{
  "count": 10,
  "next": null,
  "previous": "http://site.tld/api/items/?start=4"
  "results": [
    {
      "url": "http://site.tld/api/items/1.json",
      "title": "test",
      "description": "",
      "user": "http://site.tld/api/users/4.json",
      "creation_datetime": "2013-05-08T14:31:43.428"
    },
    {
      "url": "http://site.tld/api/items/2.json",
      "title": "test2",
      "description": "",
      "user": "http://site.tld/api/users/1.json",
      "creation_datetime": "2013-05-08T14:31:43.428"
    },
    {
      "url": "http://site.tld/api/items/3.json",
      "title": "test3",
      "description": "",
      "user": "http://site.tld/api/users/2.json",
      "creation_datetime": "2013-05-08T14:31:43.428"
    }
  ]
}

我怎样才能让一个$resource映射到这一点? 如果我使用isArray=false ,我会得到整个BLOB作为一个对象,可用于阅读,但我不能说.put()就可以了。 如果我使用isArray ,这是行不通的。

有没有干净的方式做到这一点? 或者我应该回去使用$http

Answer 1:

你有几个选项。 如果你可以改变服务器的输出,你可以添加元信息(计数,下一个,上)的标头值,而不是在响应主体加入其中。

你的第二个选择是改造与transformResponse响应。 这是可作为角一个$响应配置V1.1.2和以后 (不稳定分支):

var Data = $resource('./data.json',{},{
  list:{isArray:true,method:'get',
    transformResponse: function (data, headers) {
      return JSON.parse(data).results; 
   }}
});

如果你不希望使用不稳定的分支,也可以改变$ HTTP,其中价值资源的使用:

$http.defaults.transformResponse.push(function(data){
  if(data && data.results){
    return data.results;
  }
});

我已经创建了两个例子plunker: http://plnkr.co/edit/PmYotP0eo5k41Z6ZCxl4?p=preview

我不知道什么传递的元数据到应用程序的其它部分的最佳方法(如果需要的话)。 你可以将其追加到第一个结果,或将其添加为一个单独的对象 - 也许不那么优雅,但它会完成这项工作。



Answer 2:

我知道这个问题是有点老了。 但我认为,答案不包括主要的问题 - 如何获取分页信息以及如何保持资源特色为对象的名单。

你有basicly两种解决方案,分页程序的数据传递到头变换中的信息或使用$ HTTP,然后手动实例化项目。

1.Transform消息

在这里,我重新定义查询,把拼版数据为标题。

集管不是数组 - 它是“headersGetter”,其通过调用标题(“页眉名称”)返回报头,并通过调用标头返回内对象()。 我要设置标题小写。

var PAGINATION_TOTAL = 'pagination-total-elements';
var PAGINATION_SIZE = 'pagination-size';

...

.factory('BeerResourceFactory', function($resource, API_URI) {
        return $resource(API_URI + '/beer/:id',
            {'id': '@id'},
            {
              'update': {method: 'PUT'},
              'query' : {method: 'GET', isArray:true, transformResponse : function(data, headers) {
                var jsonData = JSON.parse(data);
                headers()[PAGINATION_TOTAL] = jsonData.totalElements;
                headers()[PAGINATION_SIZE] = jsonData.size;

                return jsonData.content;
              }}
            });
      })

从那以后,我定义服务,这种封装和头采取分页。 Sudenly我们不能用$ promise.then()和retrurn结果,因为承诺得到只会导致作为参数,而不是headersGetter,所以我们必须使用普通的回调,并创建自己的诺言。

.service('beerService', function(BeerResourceFactory, $q) {
    this.query = function(filter) {

          var defer = $q.defer();

          BeerResourceFactory.query(filter, function(result, headers) {
            var promiseResult =  {
              beers: result,
              paging: {
                totalItems: headers(PAGINATION_TOTAL),
                perPage: headers(PAGINATION_SIZE)
              }
            };

            defer.resolve(promiseResult);
          });

          return defer.promise;
    }

2,使用$ http和实例资源

当使用$ http来代替资源,还有就是你仍然想使用数组的元素作为资源实例,并能够调用$保存/ $删除的问题,所以它是可以手动实例化它们。 在这里,您也可以使用普通的承诺作为ussual。

.service('beerService', function($http, BeerResourceFactory, API_URI) {
    this.query = function(filter) {
        return $http.get(API_URI + '/beer', {params: filter})
              .then(function(response) {

                var transformedList = response.data.content.map(function(element) {
                  return new BeerResourceFactory(element);
                });

                return {
                  beers: transformedList,
                  paging: {
                    totalItems: response.data.totalElements,
                    perPage: response.data.size
                  }
                };
              });
         };

我宁愿第二个解决方案,因为它更简单。



Answer 3:

我难倒了这个问题为好,这里是为我工作。 添加响应变压器它会使用数组结果和手动创建的资源对象,我以为ngResource会在内部做无妨。

  var Plan =  $resource(apiPath + 'plans/:planId/', {planId:'@id'}, {
    query: {
      isArray: false,
      transformResponse: function(response){
        response = angular.fromJson(response);
        response.results = response.results.map(function(plan) {
          return new Plan(plan);
        });
        return response;
      }
    },
  });


Answer 4:

到现在为止,这是更老,但我设法在一个单一的资源工厂来解决这个问题:

.factory('BeerResourceFactory', function($resource, API_URI) {
    var resource = $resource(API_URI + '/beer/:id',
        {'id': '@id'},
        {
          'update': {method: 'PUT'},
          'query' : {method: 'GET', isArray:true, transformResponse : function(data) {
            var jsonData = angular.fromJson(data);
            jsonData.beers = jsonData.beers.map(function (beer) {
                return new resource(beer)
            });

            return jsonData.content;
          }}
        });
      return resource;
  })


文章来源: How to handle pagination and count with angularjs resources?