在大多数情况下,<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>
我的问题是每个列表响应被封装在一个对象中,除了实际列表之外,还有一些元属性(排序信息等),所以返回的最终对象是这样的:< / p>
{ order_field: "name", items: [{..}, {..},{..}] }
现在,我如何使用ng-repeat / ng-class创建与之前相同的东西?
<tr ng-repeat="item in responseData.items" ng-class="????">..</tr>
上一个方法无效,因为“{1}}上定义的”foo“方法不在responseData
对象上定义
有没有办法直接扩展用于实例化列表中对象的基类?
谢谢!
答案 0 :(得分:53)
我之前发现了这个问题,解决方案似乎是transformResponse
,正如John Ledbetter在另一个答案中所说的那样。
无论如何,如果你需要保留整个对象,并且在'items'中的数组中填充了资源的实例,你可以使用以下技巧来实现:< / p>
以约翰的答案为例,并对其进行修改:
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;
}]);
答案 1 :(得分:9)
如果您正在使用angular-resource 1.1.5(据我所知,它实际上可以正常使用角度1.0.7),那么在覆盖{{1}时可以指定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
这样做的缺点是您无法访问响应中不在项目内部的任何外部字段。我仍然在努力想出一种保存元数据的方法。
答案 2 :(得分: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;
});
答案 3 :(得分:0)
您可以将元数据放在标题中。我总是把分页数据放在那里。那样你的查询仍然会返回一个数组,我认为这是一件好事。查询应该返回数据数组,而不是单个数据。