2014-01-27 23 views
13

問題:angular.forEach和對象

我做的(我認爲是,但也許不是)一個簡單的angular.forEach一個數組,然後使用$resource使基於返回的每個值調用。每次調用的結果都是一個對象,就像我期待的那樣。但是,我無法讓這些物體以angular.forEach documentation演示的方式和諧相處。

但首先,一些代碼工作,然後看看失敗的代碼。

作品

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調用中獲得價值的問題,但在這種情況下如何做到這一點我有點困惑。

回答

17

是這樣的嗎?

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); 
}); 
+0

我被多麼優雅和簡單的這一解決方案是地板很好的例子。正是我需要的。 –

+1

這就是你的AngularJS,@jodytate :) – finishingmove

+0

當你簡單地使用Array.map將每個元素(或索引)映射到一個promise數組時,使用'foreach'來構建一個數組似乎是多餘的,然後你可以傳遞給' $ q.all' –

2

.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財產。

4

documentation有此

var values = {name: 'misko', gender: 'male'}; 
var log = []; 
angular.forEach(values, function(value, key) { 
    this.push(key + ': ' + value); 
}, log);