我有this example个基本列表,可以选择删除项目。
当用户尝试删除某些内容时,需要进行确认。而且,为了证明哪个项目将被删除,我已经有条件地更改了表格行颜色。
问题是,我无法在$scope.$apply()
语句之前使用confirm()
来更改所选行的颜色。
$scope.removeEntry = function(index) {
$scope.entries[index].toBeRemoved = true;
$scope.$apply();
if (confirm("Are you sure you want to delete this item?") === true) {
$scope.entries.splice(index, 1);
}else{
$scope.entries[index].toBeRemoved = false;
}
};
但是这给了我:
错误:[$ rootScope:inprog] $申请已在进行中
我是否遗漏了某些东西,或者有更好的方法来阻止这种情况吗?
我已经在this answer上尝试了几乎所有建议而没有成功。
答案 0 :(得分:1)
您的案例的解决方案是使用角度为http://plnkr.co/edit/ZDkGMqmwtxh7HSvBEWYp?p=preview
的$timeout
以下是$ apply vs $ timeout讨论的帖子:Angular $scope.$apply vs $timeout as a safe $apply
$scope.removeEntry = function(index) {
$scope.entries[index].toBeRemoved = true;
$timeout(function() {
if (confirm("Are you sure you want to delete this item?") === true) {
$scope.entries.splice(index, 1);
}else{
$scope.entries[index].toBeRemoved = false;
}
})
};
你必须搞砸了正确实施它。
答案 1 :(得分:1)
另一种解决方案可以帮助您解决这个问题。您可以使用Angular中的$evalAsync
。
var app = angular.module('plunker', [])
.controller('ListController', ['$scope', '$timeout', function($scope, $timeout) {
$scope.entries = [{name:"potatoes"},
{name:"tomatoes"},
{name:"flour"},
{name:"sugar"},
{name:"salt"}];
$scope.removeEntry = function(index) {
$scope.entries[index].toBeRemoved = true;
$evalAsync(function() {
if (confirm("Are you sure you want to delete this item?") === true) {
$scope.entries.splice(index, 1);
}else{
$scope.entries[index].toBeRemoved = false;
}
})
};
}]);
在$evalAsync
和$timeout
之间选择取决于您的情况:
如果代码使用 $evalAsync
从指令排队,则应该在Angular操纵DOM之后但在浏览器呈现之前运行。
如果代码使用 $evalAsync
从控制器排队,它应该在Angular操纵DOM之前运行(并且在浏览器渲染之前) - 很少你想要这个
如果代码使用 $timeout
排队,它应该在Angular操纵DOM之后运行,并在浏览器渲染之后运行(在某些情况下可能会导致闪烁)