如何防止此案件中的$ apply已在进行中?

时间:2015-07-08 12:12:03

标签: angularjs

我有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上尝试了几乎所有建议而没有成功。

2 个答案:

答案 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之后但在浏览器呈现之前运行。

    < / LI>
  • 如果代码使用 $evalAsync 从控制器排队,它应该在Angular操纵DOM之前运行(并且在浏览器渲染之前) - 很少你想要这个

  • 如果代码使用 $timeout 排队,它应该在Angular操纵DOM之后运行,并在浏览器渲染之后运行(在某些情况下可能会导致闪烁)