您遇到的行为在某种程度上与以下事实有关:在 $resource query() 中,预期的响应数据是一个数组,该数组中的每个数据项都被转换为包含实例操作方法的资源对象后缀为$。
正如您在上面的 Resource Object Reference 中看到的,它执行数组中数据项的 shallowClearAndCopy() 副本,从而增强了使用仅迭代 enumerable 属性的 for..in 将数据项添加到资源对象本身。由于 Array.length 不是可枚举属性,因此不会从数组数据项中扩充 Resource 对象中的 length 属性。
你有三种方法可以解决这个问题:
[1] 您可以创建一个自定义操作方法,该方法具有与query() 操作方法相同的属性,但具有额外的transformResponse() 定义。 transformResponse() 方法在发出请求之后但在任何承诺被解决之前触发。它与 JSON 字符串一起传递,您可以通过 angular.fromJson() 将其转换为常规 json 对象并遍历所有数组并使用新的可枚举属性扩充每个项目对象,我们将其称为 ._length 然后返回新的用于接收承诺的反序列化对象。这样,shallowClearAndCopy() 方法复制可枚举的_length 属性并将其扩充到资源对象。
代码如下所示:
DEMO
var DataResource = $resource('data.json', null, {
'getData': {
method: 'GET',
isArray: true,
transformResponse: function(response) {
var newData = JSON.parse(response);
newData.map(function(data) {
data._length = data.length;
return data;
});
return newData;
}
}
});
DataResource.getData(function(data) {
console.log(data);
});
您应该注意到,在console.log() 中,它显示每个资源对象项都有一个您可以使用的_length 属性。
[2] 另一种方法是将$http 服务用于此特定用例,这是我能想到的解决此问题的最简单方法。
$http.get('data.json').success(function(data) {
console.log(data);
});
[3] 重新考虑您的响应数据的结构,如下所示:
[{
item: [1,2,3,4,5]
}, {
item: [1,2,3,4,5]
}, {
item: [1,2,3,4,5]
}, {
item: [1,2,3,4,5]
}];
然后您可以简单地使用$resource 工厂并使用item 键迭代到每个数组项对象。