Angular.forEach и объекты
Проблема:
Я делаю (что, по-моему, но, возможно, нет), просто angular.forEach
над массивом, а затем используя $resource
, чтобы сделать вызов на основе каждого возвращаемого значения. Результатом каждого вызова является объект, как я ожидаю. Но я не могу заставить эти объекты гармонично объединиться в том, как демонстрируется angular.forEach документация.
Но сначала, какой-то код, который работает, а затем посмотрите на код, который терпит неудачу.
Работы
var uniqueIds = {};
angular.forEach(object, function(key, value){
this.push(key.uniqueIds);
}, uniqueIds);
console.log(uniqueIds)
// uniqueIds equals the expected array
Не удается
Здесь, где вещи становятся хитрыми. Теперь, в следующем примере, внутри angular.forEach
есть вызов $resource
.
angular.forEach(array, function(index){
Resource.query({id:index}, function(result){
console.log(result)
// returns the expected object,
// but, as expected, I can't access the object outside the async call
});
console.log(result);
// result is undefined
});
Учитывая асинхронность, кажется, что обещание может решить проблему. Но это не так... Я все еще в асинхронном разговоре. Не назначается result
$scope
. Короче говоря, я не могу получить значение вне Resource.query
.
Что мне нужно делать?
Мне нужен возвращаемый объект каждого вызова $resource
, чтобы добавить один объект (используя angular.extend? Я пробовал это) так же, как angular.forEach
создал массив. Я пробовал много разных подходов, большинство из них основывалось на ответах на общие асинхронные вопросы, заданные здесь, но до сих пор безрезультатно. Я уверен, что это проблема с получением значения из вызова $resource
, но как это сделать в этом случае, я немного озадачен.
Ответы
Ответ 1
Что-то вроде этого?
var promises = [];
angular.forEach(array, function(index) {
promises.push(Resource.query(...));
});
$q.all(promises).then(function(result1, result2, result3 ...) {
// do stuff with result1, result2 ... or
// var results = Array.prototype.slice.call(arguments);
});
Ответ 2
Angular документация имеет очень хороший пример для этого
var values = {name: 'misko', gender: 'male'};
var log = [];
angular.forEach(values, function(value, key) {
this.push(key + ': ' + value);
}, log);
Ответ 3
.query
возвращает ссылку на массив, которая заполняется данными при завершении xhr.
Поскольку, возможно, id
является уникальным идентификатором, запрос возвращает массив с одним элементом, поэтому я предлагаю вам вместо этого использовать .get
.
В любом случае, если вы все еще намерены использовать .query
, вы можете сделать что-то вроде:
var arrays = [];
angular.forEach(array, function(index){
arrays.push(Resource.query({id:index}, function(result){
console.log(result)
// returns the expected object,
// but, as expected, I can't access the object outside the async call
}));
console.log(result);
// result is undefined
});
$scope.$watch(function () {
return arrays;
}, function (arrays) {
angular.forEach(arrays, function (array) {
angular.forEach(array[0], function () {
//Do something with the object fields
});
});
});
Как вы видите, код выглядит довольно плохо...
Для достижения лучшего результата вы можете использовать:
var objects = [];
angular.forEach(array, function(index){
objects.push(Resource.get({ id:index });
});
$scope.$watch(function () {
return objects;
}, function (objects) {
angular.forEach(objects, function (obj) {
angular.forEach(obj, function () {
//Do something with the object fields
});
});
});
Еще лучше, если вы позволите AngularJS сделать $watch
, присвоив objects
свойству $scope
.