28

次のような JSON を出力する API 用の angularjs クライアントを構築する必要があります。

{
  "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と、ブロブ全体が 1 つのオブジェクトとして取得され、読み取りに使用できるようになりますが、それを呼び出すことはできません.put()。を使用するisArrayと、機能しません。

これを行うためのきれいな方法はありますか?または、使用に戻る必要があり$httpますか?

4

4 に答える 4

16

この質問は少し古いことを知っています。しかし、答えは主な問題をカバーしていないと思います-ページネーション情報を取得する方法と、オブジェクトのリストのリソース機能を保持する方法。

基本的に 2 つの解決策があります。ページネーター データを変換メッセージのヘッダーに渡すか、$http を使用してアイテムを手動でインスタンス化します。

1.メッセージの変換

ここでは、クエリを再定義して、ページネーション データをヘッダーに挿入します。

Headers は配列ではありません。headers('Header-Name') を呼び出してヘッダーを返し、headers() を呼び出して内部オブジェクトを返すのは「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;
              }}
            });
      })

その後、これをカプセル化し、ヘッダーからページネーションを取得するサービスを定義します。$promise.then() を使用して結果を返すことはできません。プロミスは引数として結果のみを取得し、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 を使用する場合、依然として配列の要素をリソース インスタンスとして使用し、$save / $delete を呼び出すことができるという問題があるため、それらを手動でインスタンス化することができます。ここでは通常の promise を通常どおり使用することもできます。

.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
                  }
                };
              });
         };

より単純なため、2番目のソリューションをお勧めします。

于 2015-03-17T23:28:18.537 に答える
2

私もこの問題に悩まされましたが、これが私のために働いたものです。配列の結果を受け取り、リソース オブジェクトを手動で作成する応答トランスフォーマーを追加します。

  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;
      }
    },
  });
于 2016-04-18T10:20:51.487 に答える
0

今ではこれはさらに古いですが、単一のリソース ファクトリでこれを解決することができました。

.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;
  })
于 2015-06-29T13:54:51.070 に答える