我想创建一个find方法来遍历Angular中$resource
服务返回的数组。
如果我有这样一个服务:
'use strict';
angular.module('adminApp').factory('ProductType', function($resource) {
var ProductType;
ProductType = $resource('http://localhost:3000/api/v1/product_types/:id.json', {
id: '@id'
}, {
update: {
method: 'PUT'
}
});
ProductType.find = function(typeName){
var types = this.query(),
typeObject = {},
self = this;
for(type in types) {
var result = types[type],
resultName = self.normalizeName(result.name),
if(typeName === resultName) {
typeObject = result;
}
}
return typeObject;
};
return ProductType;
});
我试着把它全部包装在一个函数中,并返回函数,认为它与异步有关,我还试着在查询方法中嵌套一个回调,但这只是允许我修改响应,而不是实际返回任何不同的东西。
当我尝试将返回值设置为控制器中的$scope
时,我得到一个空白对象
this.query()
方法将返回一个数组,该数组可能不会被填充,直到this.query()方法从服务器获得其结果。您将需要执行类似的操作,直到对服务器的调用完成。因为这是异步的,你需要从这个方法返回一个承诺,当初始查询完成,你已经搜索了结果。
'use strict';
angular.module('adminApp').factory('ProductType', [
'$q',
'$resource',
function($q, $resource) {
var ProductType;
ProductType = $resource('http://localhost:3000/api/v1/product_types/:id.json', {
id: '@id'
}, {
update: {
method: 'PUT'
}
});
ProductType.find = function(typeName) {
var defer = $q.defer(),
types = this.query(),
self = this;
types.$promise.then(function () {
var result,
resultName,
typeObject,
type;
for(type in types) {
result = types[type];
resultName = self.normalizeName(result.name);
if(typeName === resultName) {
typeObject = result;
break;
}
}
defer.resolve(typeObject);
}, function (err) {
// the called failed
defer.reject(err);
})
return defer.promise;
};
return ProductType;
}]);
取自angular文档https://docs.angularjs.org/api/ngResource/service/$resource
重要的是要意识到调用$resource object方法会立即返回一个空引用(对象或数组取决于isArray)。一旦数据从服务器返回,就用实际数据填充现有引用。这是一个有用的技巧,因为通常资源被分配给一个模型,然后由视图渲染。使用空对象导致不呈现,一旦数据从服务器到达,则用数据填充对象,视图自动重新呈现自身,显示新数据。