我正在使用AngularJS和Angular Translate。我有一个具有'key'属性的对象数组 - 一个应该被翻译的字符串。
这是我的对象数组:
var objects = [{
id: 1,
key: 'Jacket'
}, {
id: 2,
key: 'Trousers'
}, {
id: 3,
key: 'Hat'
}];
这些是我的翻译:
var translationsEN = {
Jacket: 'This is Jacket in English',
Trousers: 'This is Trousers in English',
Hat: 'This is Hat in English'
}
当某些特定事件发生时,我需要一个对象数组,但需要翻译,而不是键。这就是为什么我有一个执行以下功能的功能:
var translatedObjects = [];
for (var i = 0; i < objects.length; i++) {
$translate(objects[i].key).then(function (translation) {
translatedObjects[i] = translation;
});
}
执行函数后,存储在translatedObjects数组中的结果为:
[null,null,null,"This is Hat in English"]
我猜这种情况正在发生,因为我实际上正在执行对$ translate服务的异步调用,而translateObject [i]实际上并没有指向正确的对象,因为'i'没有在当前上下文中定义。
那么,如何执行异步函数调用并正确分配我的数组,如上例所示?
答案 0 :(得分:1)
您可以使用push
数组方法插入数据。不需要传递i
,因为它将以相同的顺序插入。
for (var i = 0; i < objects.length; i++) {
$translate(objects[i].key).then(function (translation) {
$scope.translatedObjects.push(translation);
});
}
答案 1 :(得分:1)
是的,当回调触发时,for循环将完成,i
的值将为3
。然后三个回调将覆盖相同索引的值三次。
您可以将变量封装在新范围中:
for (var i = 0; i < objects.length; i++) {
$translate(objects[i].key).then((function(x) {
return function (translation) {
translatedObjects[x] = translation;
};
})(i));
}
上面的内容是创建一个接受参数x
的匿名函数,并返回一个回调函数。因此,当您调用该函数传递i=0
时,它将返回一个回调函数,该函数可以从创建它的作用域访问x=0
。在下一次迭代中,将再次调用匿名函数,并返回一个新的回调函数,其中x
为1,等等。
如果您知道将同步调用回调,并且只想分配给数组,那么ngLover的答案可能更具可读性。
答案 2 :(得分:0)
您已使用承诺,因此可以使用Promise.all()
:
var promises = [];
for (var i = 0; i < objects.length; i++) {
promises.push($translate(objects[i].key));
}
Promise.all(promises).then(function (translatedObjects) {
// use your array here
});