You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用$apply执行多操作时出现[$rootScope:inprog]错误,求代码修复方案

这个错误我之前也碰到过!本质原因就是你在Angular的消化周期已经在运行的时候,又手动触发了$scope.$apply(),而且你的代码里还连续调用了两次——哪怕前面有!$scope.$$phase的判断,第二次调用还是会撞进正在进行的周期里。

先说说你代码里的问题

  1. 你先判断!$scope.$$phase然后调用了一次$apply,紧接着又直接调用了一次$scope.$apply():第一次$apply已经启动了消化周期,这个周期还没走完,第二次调用自然就会触发冲突错误。
  2. 额外提一句:$$phase是Angular的内部私有属性,官方其实不推荐依赖它来判断是否要调用$apply,它可能在后续版本里发生变化。

解决方案:简化你的$apply调用

其实你的场景里,大部分情况下根本不需要手动调用$apply!因为$scope.update是控制器里的方法,本身就在Angular的上下文当中,Angular会自动跟踪$scope.PatternData的变化,触发脏检查和消化周期。

方案1:直接移除多余的$apply

这是最简洁的修改方式:

$scope.update = function () { 
    //更新前移除列表中的空行
    if ($scope.PatternData.length > 1) { 
        removeEmptyRow($scope.PatternData); 
    } 
    // 这里不需要手动调用$apply,Angular会自动处理$scope的变化
    //更新数据
    orderPatternService.updatePattern(function () { 
        //重载数据表
        $scope.tableParams.reload(); 
        //显示通知
        $timeout(function () { 
            notifyService.popEdit(); 
        }); 
    },$scope.PatternData); 
};

方案2:如果removeEmptyRow需要强制触发消化周期

如果removeEmptyRow是脱离Angular上下文的操作(比如直接操作数组但没触发Angular的脏检查),那可以把这个修改操作包裹在一次$apply的回调里,既确保Angular跟踪变化,又不会重复触发:

$scope.update = function () { 
    //更新前移除列表中的空行
    if ($scope.PatternData.length > 1) { 
        $scope.$apply(function() {
            removeEmptyRow($scope.PatternData); 
        });
    } 
    //更新数据
    orderPatternService.updatePattern(function () { 
        $scope.tableParams.reload(); 
        $timeout(function () { 
            notifyService.popEdit(); 
        }); 
    },$scope.PatternData); 
};

另外,你在异步回调里用$timeout是非常正确的选择——$timeout会自动触发$apply,确保notifyService.popEdit()的操作能被Angular感知到。

内容的提问来源于stack exchange,提问作者Triet Pham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:19:00