I'm looping through some items in AngularJS and asking user input on each item using an AngularUI modal. My problem is that the loop finishes and all the modals render at once, without waiting for the user.
我在用AngularJS遍历一些项目,并使用AngularUI模式询问用户对每个项目的输入。我的问题是循环结束并且所有的modals同时呈现,而不需要等待用户。
How can I make execution wait until the modal is closed?
我怎样才能在模式关闭之前执行?
An example of my code:
我的代码示例:
var listofitems = somelist;
// loop through each item
for (var i in listofitems){
if (listofitems[i].id == presetId){
// ask user confirmation in a modal
$scope.selections = {'doThis': doThis,
'doThat': doThat}
var openModal = function () {
var modalInstance = $modal.open({
templateUrl: 'confirmationModal.html',
controller: confirmationController,
resolve: {
selections: function () {
return $scope.selections;
}
}
});
modalInstance.result.then(function (selections) {
doThis = selections.doThis;
if (selections.doThat){
doThis = selections.doThis;
}
});
}
// open the modal
openModal();
}
}
}
var confirmationController = function ($scope, $modalInstance, selections) {
$scope.selections = selections;
$scope.doThis = function () {
$scope.selections.doThis = true;
$modalInstance.close($scope.selections);
};
$scope.doThat = function () {
$scope.selections.doThat = true;
$modalInstance.close($scope.selections);
};
};
Incorporating @dsfg answer here's a Plunkr example. The ui modals don't work that well, but you can see execution has finished before the user has submitted any input.
结合@dsfg的答案,这里有一个Plunkr的例子。ui modals不能很好地工作,但是您可以看到在用户提交任何输入之前执行已经完成。
1 个解决方案
#1
2
You can't just pause the loop (well you can with ES6 generators). But you can change the way you iterate over array/object keys. What you can do is to check items one by one using function and execute next "iteration" only when previous is completed. This is easy with promises.
不能只是暂停循环(可以使用ES6生成器)。但是可以更改遍历数组/对象键的方式。您可以做的是使用函数逐个检查项目,并只在完成前一项时执行下一项“迭代”。承诺很容易做到。
At first, make openModal
return promise, then create helper function checkItems
that will be invoked for every item in array of keys.
首先,创建openModal return promise,然后创建helper函数checkItems,它将为键数组中的每个项调用。
var openModal = function() {
var modalInstance = $modal.open({
templateUrl: 'confirmationModal.html',
controller: confirmationController,
resolve: {
selections: function() {
return $scope.selections;
}
}
});
return modalInstance.result.then(function(selections) {
doThis = selections.doThis;
if (selections.doThat) {
doThis = selections.doThis;
}
});
};
var listofitems = somelist;
var keys = Object.keys(listofitems);
(function checkItems() {
// get the first key and remove it from array
var key = keys.shift();
if (listofitems[key].id == presetId) {
// ask user confirmation in a modal
$scope.selections = {
'doThis': doThis,
'doThat': doThat
}
// open the modal
openModal().then(function() {
if (keys.length) {
checkItems();
}
});
}
})();
In above example, items will be checked until the first promise is rejected. If you want to check all items regardless of the promise state then use
在上面的例子中,项目将被检查直到第一个承诺被拒绝。如果您想要检查所有项目,不管承诺状态是什么,然后使用
openModal().finally(function() {
if (keys.length) {
checkItems();
}
});
#1
2
You can't just pause the loop (well you can with ES6 generators). But you can change the way you iterate over array/object keys. What you can do is to check items one by one using function and execute next "iteration" only when previous is completed. This is easy with promises.
不能只是暂停循环(可以使用ES6生成器)。但是可以更改遍历数组/对象键的方式。您可以做的是使用函数逐个检查项目,并只在完成前一项时执行下一项“迭代”。承诺很容易做到。
At first, make openModal
return promise, then create helper function checkItems
that will be invoked for every item in array of keys.
首先,创建openModal return promise,然后创建helper函数checkItems,它将为键数组中的每个项调用。
var openModal = function() {
var modalInstance = $modal.open({
templateUrl: 'confirmationModal.html',
controller: confirmationController,
resolve: {
selections: function() {
return $scope.selections;
}
}
});
return modalInstance.result.then(function(selections) {
doThis = selections.doThis;
if (selections.doThat) {
doThis = selections.doThis;
}
});
};
var listofitems = somelist;
var keys = Object.keys(listofitems);
(function checkItems() {
// get the first key and remove it from array
var key = keys.shift();
if (listofitems[key].id == presetId) {
// ask user confirmation in a modal
$scope.selections = {
'doThis': doThis,
'doThat': doThat
}
// open the modal
openModal().then(function() {
if (keys.length) {
checkItems();
}
});
}
})();
In above example, items will be checked until the first promise is rejected. If you want to check all items regardless of the promise state then use
在上面的例子中,项目将被检查直到第一个承诺被拒绝。如果您想要检查所有项目,不管承诺状态是什么,然后使用
openModal().finally(function() {
if (keys.length) {
checkItems();
}
});