37

ほとんどの場合、<custom-resource>.query()メソッドの結果は配列であり、次の (ファクトリ) コードを使用していくつかのメソッド (ビジネス ロジック) で簡単に拡張できます。

var Data = $resource('http://..');
Data.prototype.foo = function() {return ...};

これは、次のように ng-repeat / ng-class で使用するのに最適です。

<tr ng-repeat="item in responseData" ng-class="{warning: item.foo()}">..</tr>

私の問題は、すべてのリスト応答が、実際のリストに加えて、いくつかのメタ プロパティ (並べ替え情報など) を持つオブジェクトにカプセル化されているため、返される最終的なオブジェクトは次のようになることです。

{ order_field: "name", items: [{..}, {..},{..}] }

さて、ng-repeat/ng-class で以前と同じものを作るにはどうすればよいでしょうか?

<tr ng-repeat="item in responseData.items" ng-class="????">..</tr>

「foo」メソッドはオブジェクトではなくオブジェクトで定義されているため、前のメソッドは機能しresponseDataませんitem

リスト上のオブジェクトをインスタンス化するために使用される基本クラスを直接拡張する方法はありますか?

ありがとう!

4

4 に答える 4

53

transformResponseジョン・レッドベターが他の回答で述べているように、私は以前にその問題を発見しました。

とにかく、オブジェクト全体を保持する必要があり、リソースのインスタンスで満たされた 'items' の配列を保持する必要がある場合は、次のトリックでそれを実行できる可能性があります。

ジョンの答えから例を取り、それを少し変更します。

angular.module('foo')

  .factory('Post', ['$resource', function($resource) {

    var Post = $resource('/api/posts/:id', { id: '@id' }, {
      query: {
        method: 'GET',
        isArray: false, // <- not returning an array
        transformResponse: function(data, header) {
          var wrapped = angular.fromJson(data);
          angular.forEach(wrapped.items, function(item, idx) {
             wrapped.items[idx] = new Post(item); //<-- replace each item with an instance of the resource object
          });
          return wrapped;
        }
      }
    });

    Post.prototype.foo = function() { /* ... */ };

    return Post;
  }]);
于 2013-06-17T14:11:30.150 に答える
4

これは古い質問ですが、私は自分でこの問題に遭遇しました。gargc のソリューションは正しいアプローチですが、改善点があります。transformResponseサービスに渡される配列を受け入れ$httpます。変換関数を完全に置き換えるのではなく、変換をデフォルトに追加して、必要な更新のみを行うことができます。

angular.module('foo')
    .factory('Post', function ($resource, $http) {
        var Post = $resource('/api/posts/:id', { id: '@id' }, {
            query: {
                method: 'GET',
                isArray: false,
                transformResponse: $http.defaults.transformResponse.concat(function(data, header) {
                    angular.forEach(data.items, function(item, idx) {
                        data.items[idx] = new Post(item);
                    });
                    return data;
                })
            }
        });

        Post.prototype.foo = function() { /* ... */ };

        return Post;
    });
于 2015-01-04T18:25:34.110 に答える