角 - 自定义方法扩展$资源子对象角 - 自定义方法扩展$资源子对象(Angular - exten

2019-05-13 01:37发布

在大多数情况下的结果<custom-resource>.query()方法是一个数组,可以用一些方法(业务逻辑)用下面的(工厂)码容易地被扩展:

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

这是完美的与NG-重复/ NG级使用,就像这样:

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

我的问题是, 每一个列表响应被封装在一个对象,其中除了实际的名单,有一些元属性(分类信息等),所以返回的最终目标是这样的:

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

现在,我怎么做同样的事情,以前用NG-重复/ NG级?

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

作为“foo”的方法被定义在以前的方法是行不通的responseData而不是item对象

有什么办法可以直接扩展用于列表实例化对象的基类?

谢谢!

Answer 1:

我以前就发现问题,解决方案似乎是transformResponse ,如约翰·莱德贝特在对方回答说。

无论如何, 如果你需要保持整个对象 ,并且还具有填充有资源的情况下,“项目”的数组,你也许可以用下面的技巧来做到这一点:

采取例如,从约翰的回答,并修改了一点:

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


Answer 2:

如果您使用的角度,资源1.1.5(其中据我其实可以告诉工作与角1.0.7精),有一个transformResponse你可以重写时,指定选项$resource的方法:

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

    var Post = $resource('/api/posts/:id', { id: '@id' }, {
      query: {
        method: 'GET',
        isArray: true,
        transformResponse: function(data, header) {
          var wrapped = angular.fromJson(data);
          return wrapped.items;
        }
      }
    });

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

    return Post;
  }]);

如果你这样做,你不再需要手动拉项目从包装的响应,并且每个项目将是一个实例Post可以访问的.foo方法。 你可以这样写:

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

这样做的缺点是你失去任何在你的回应外场不属于内部项目的访问权。 我仍然在努力找出一种方法来保存元数据。



Answer 3:

这是一个老问题,但我只是碰到了这个问题我自己。 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;
    });


Answer 4:

你可以把元数据中的标头。 我总是把传呼数据存在。 这样,你的查询仍然会返回一个数组,我相信这是一件好事。 查询应该返回数据,而不是单个数据的阵列。



文章来源: Angular - extending $resource subobject with custom methods