我正在尝试从 $resource 查询的返回创建一个对象数组,如以下问题所示:link 。但是,我不断获得相同的资源和其他元素列表。我有一个笨蛋:here (您必须打开开发者控制台才能查看输出。)
var app = angular.module('plunker', ['ngResource']);
app.factory('NameResource', function($resource) {
var url = 'data.json';
var res = $resource(url, null, {
query: {
method: 'GET',
isArray: true,
transformResponse: function(data, headersGetter) {
var items = angular.fromJson(data);
var models = [];
angular.forEach(items, function(item) {
models.push(item);
});
console.log("models: ", models);
return models;
}
}
});
return res;
});
app.controller('MainCtrl', function($scope, NameResource) {
$scope.names = NameResource.query();
console.log('Inside controller: ', $scope.names);
setTimeout(function(){console.log('after some time names is:', $scope.names)}, 3000);
});
我做错了什么?或者我误解了什么。还有这两者有什么区别呢?它似乎对我来说非常相似。什么时候会引起问题?
最佳答案
Resource.query
返回一个带有两个属性的数组(因为您创建了 isArray
标志),$promise
是 promise 解析后会将所有响应值“复制”到从 Resource.query
返回的数组中,神奇地更新 View 和 $resolved
这是一个标志,告诉 $promise
已经解决了,为了回答你的问题,实际上发生了一些额外的转换,从你的转换返回的数据实际上会经过另一个转换(无法禁用),这就是你的每个对象被转换成一个资源
实例。
这就是您期望发生的情况:
promise
.then(function (rawData) {
// this is where your transformation is happening
// e.g. transformResponse is called with rawData
// you return your transformed data
})
.then(function (transformedData) {
// raw data has gone through 1 transformation
// you have to decide what to do with the data, like copying it to
// some variable for example $scope.names
})
但是Resource
正在执行以下操作:
promise
.then(function (rawData) {
// this is where your transformation is happening
})
.then(function (transformedData) {
// Resource is adding this handler and doing the
// 'copy' to array operation here for you,
// but it will actually create a Resource instance
// in the process with each item of your array!
})
.then(function (transformedDataV2) {
// raw data has gone through 2 transformations here!
})
如果我们看一下源代码 these,那么额外的转换就是神奇发生的地方,也是创建 Resource
实例的地方。是负责此转换的行,我将它们复制到此处:
if (action.isArray) {
value.length = 0;
forEach(data, function(item) {
if (typeof item === "object") {
value.push(new Resource(item));
} else {
// Valid JSON values may be string literals, and these should not be converted
// into objects. These items will not have access to the Resource prototype
// methods, but unfortunately there
value.push(item);
}
});
}
data
是第一次转换返回的数据,如上所示,它将传递 typeof item === 'Object'
检查,因此 value
是 Resource.query
返回的数组,已使用新的 Resource
项(而不是 item)进行更新。你担心这个奇怪的Resource
对象,我们来分析一下Resource
constructor :
function Resource(value) {
shallowClearAndCopy(value || {}, this);
}
它只是将对象 value
的每个属性复制到 this
(this
是新的 Resource 实例),所以现在我们'正在处理 Resource
对象而不是普通数组对象
will it cause an issue?
如果您定义的转换函数稍微复杂一点,就像让每个对象实际上是其他对象的实例,而该对象的 __proto__
有一些方法,例如,我相信它会的。如果使用 Person
对象而不是普通对象,则 Person.prototype
中定义的方法对于整个操作的结果将不可见,因为每个对象都不是一个Person
实例,而是一个 Resource
实例! (请参阅此 plunkr 中的此错误,请务必阅读注释并查看控制台中由于未定义的方法而引发的错误)
关于javascript - angularjs $resource 将查询资源列表转换为对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28911239/