【问题标题】:How can I prevent $apply already in progress on this case?在这种情况下,如何防止 $apply 已经在进行中?
【发布时间】:2015-09-26 08:12:28
【问题描述】:

我有this example,这是一个带有删除项目选项的基本列表。

当用户尝试删除某些内容时,需要确认。而且,为了演示将删除哪个项目,我有条件地更改了表格行的颜色。

问题是,如果在confirm() 语句之前不使用$scope.$apply(),我无法更改所选行的颜色。

$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] $apply 已经在进行中

我是否遗漏了什么,或者有什么更好的方法可以防止这种情况发生?

我已经尝试了this answer 上的几乎所有建议,但均未成功。

【问题讨论】:

  • 您尝试过$timeout 解决方案吗?没有帮助吗?
  • 为什么不带任何参数调用 $scope.apply() ? apply is used to evaluate an argument you pass it
  • 我看到它在不使用 $scope.$apply(); 的情况下工作。请删除此行后再试。
  • @Vineet:摘要循环将被阻塞 confirm 打断,Patrick 需要在此之前完成。
  • @Vineet:这都是问题所在。他设置了一个属性来突出显示表格中的一行。要在 UI 中反映此更改,必须运行并完成摘要循环。并且必须在confirm弹出模态之前完成。

标签: angularjs


【解决方案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 之前(以及在浏览器呈现之前)运行——你很少需要这个

  • 1234563 p>

【讨论】:

  • 我只是在查看$evalAsync。有什么建议为什么要使用这个而不是$timeout?
  • 查看已编辑的.. 会很有帮助,因为在数据到来之前不会进行渲染
【解决方案2】:

解决您的情况的方法是使用 $timeout from angular: http://plnkr.co/edit/ZDkGMqmwtxh7HSvBEWYp?p=preview

这是关于 $apply 与 $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;
      }
    })
};

您一定是搞砸了正确实施它。

【讨论】:

  • 哈哈哈,我太笨了。我正是这样做的,但没有奏效,因为我显然忘记在控制器上注入$timeout。我现在心情不好
猜你喜欢
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-17
相关资源
最近更新 更多