【问题标题】:($rootScope:inprog) $apply already in progress($rootScope:inprog) $apply 已经在进行中
【发布时间】:2026-02-05 03:35:01
【问题描述】:

我正在尝试在刷新数据后将更改应用到 ui 网格,但出现此错误:

    angular.js:13236 Error: [$rootScope:inprog] $apply already in progress

 http://errors.angularjs.org/1.5.0/$rootScope/inprog?p0=%24apply
        at angular.js:68
        at beginPhase (angular.js:17178)
        at Scope.$digest (angular.js:16616)
        at Scope.$apply (angular.js:16928)
        at Scope.$scope.submitForm (app-controllers.js:652)
        at fn (eval at compile (angular.js:14086), <anonymous>:4:335)
        at expensiveCheckFn (angular.js:15076)
        at callback (angular.js:24546)
        at Scope.$eval (angular.js:16820)
    at Scope.$apply (angular.js:16920)

有什么问题吗?我的代码如下

获取数据

    var initialData = [] 
var getData = function (castomUrl) {
                $http.get(castomUrl)
                    .success(function (data) {
                        // console.log(data)
                        // Considering Angular UI-Grid, the data should be declared inside as scope var and put it inside gridOptions
                        $scope.initialData = data;
                        // $scope.gridOptions.data = $scope.initialData;
                        // ***
                        angular.forEach($scope.initialData, function (val) {
                            val.occuredDate = new Date(val.occuredDate);
                        });
                        // $interval whilst we wait for the grid to digest the data we just gave it
                        $interval(function () {
                            $scope.gridApi.selection.selectRow($scope.initialData[0]);
                        }, 0, 1);
                    });
            };
            getData(urlData);

点击获取行值

     gridApi.selection.on.rowSelectionChanged($scope, function (row) {
                        // api call to get row Data and update for current row
                        var dataRow = row.entity;
                        $scope.id = dataRow.id;
                        $scope.getRowData();
                    });

 $scope.getRowData = function(){
                eventService.singleEvent($scope.id)
                    .then(function (data) {
                        $scope.rowData = data.model;
                        $scope.rowKeys = Object.keys($scope.rowData);
                    }).then(function () {
                    $scope.getUpdate();
                });
            };

eventService.singleEvent 在哪里

 function singleEvent (id) {
            return $http.get(apiUrl+id)
                        .then(function (serviceResp) {
                           return serviceResp.data;
                        });
        }

以html格式显示行数据

  <form style="padding: 15px" ng-submit="submitForm(rowData)">
                                    <div class="form-group row">

                                        <div ng-repeat="(key, value) in rowData">
                                            <div ng-if="(key === 'id' || key.toLowerCase().endsWith('id') === false) ? true : false">
                                                <label for="rowData" class="col-sm-2">{{key | makeUppercase
                                                    }}</label>
                                                <div class=" col-sm-2">
                                                    <input class="form-control rowValue"
                                                           id="rowData[key]"
                                                           ng-disabled="disableInput(key)"
                                                           ng-if="!isObject(value)"
                                                           type="text"
                                                           ng-model="rowData[key]"
                                                    />
                                                    <input
                                                            class="form-control rowValue"
                                                            id="rowData[key].name"
                                                            ng-disabled="disableInput(key)"
                                                            ng-if="isObject(value) && key !== 'status' && key !== 'priority' && key !== 'severity'"
                                                            type="text"
                                                            ng-model="rowData[key].name"
                                                    />
                                                    <select ng-if="isObject(value) && key == 'status'"
                                                            ng-model="rowData.statusId"
                                                            class="form-control rowValue"
                                                            id="statusId"
                                                            ng-options='item.id as item.name for item in eventLov.statusOptions()'>
                                                        <option value=''>{{value.name}}</option>
                                                    </select>
                                                    <select ng-if="isObject(value) && key == 'priority'"
                                                            ng-model="rowData.priorityId"
                                                            class="form-control rowValue"
                                                            id="priorityId"
                                                            ng-options='item.id as item.name for item in eventLov.priorityOptions()'>
                                                        <option value=''>{{value.name}}</option>
                                                    </select>
                                                    <select ng-if="isObject(value) && key == 'severity'"
                                                            ng-model="rowData.severityId"
                                                            class="form-control rowValue"
                                                            id="severityId"
                                                            ng-options='item.id as item.name for item in eventLov.severityOptions()'>
                                                        <option value=''>{{value.name}}</option>
                                                    </select>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    <button type="submit" class="btn btn-default" ng-if="rowData">Save</button>
                                    <button type="button" class="btn btn-default" ng-if="rowData"
                                            ng-click="cancelForm()">
                                        Cancel
                                    </button>
                                </form>

提交更改

     $scope.submitForm = function (event) {
                $scope.modifyEvent(event);
                $timeout( function(){
                    $rootScope.refresh();
                }, 100);
            };

 $scope.modifyEvent = function (event) {
                // $log.info(event);
                eventService.modifyEvent(event)
            };

更新服务

 function modifyEvent (event) {
           return $http({
               method   : 'PUT',
               url      : apiUrl + event.id,
               data     : event
           }, event)
           .then(function success (result) {
               $log.info("Update Successful");
               return result.data;
           }, function error( err ) {
               $log.error(" update has been failed ", err);
           });
        }

刷新网格

$rootScope.refresh = function () {

                $log.info("fired");
                eventService.events();
                $scope.$apply();
}

刷新服务

 function events () {
        return $http.get(apiUrl)
                    .then(function (serviceResp) {
                        return serviceResp.data;
                    });
    }

最后我看到了错误

$apply 已经在进行中

但数据已上传到数据库并进行了修改。有什么问题?

【问题讨论】:

    标签: javascript angularjs rest


    【解决方案1】:

    修复 1 -

    使用

    $timeout(function(){ 
      $scope.$apply()
      ... write your code here 
    },0)
    

    当摘要循环完成时触发。

    修复 2 -

    如果摘要循环正在运行,$scope.$$phase 将返回 true,否则返回 false,但在您的情况下它不会有用,因为它不提供任何回调函数。

    也不推荐使用

    【讨论】:

      【解决方案2】:

      $timeout 回调在摘要期间运行:

                  $timeout( function(){
                      $rootScope.refresh();
                  }, 100);
      

      无需在refresh 内触发它。应该是

      $rootScope.refresh = function () {
                      $log.info("fired");
                      eventService.events();
      }
      

      避免$rootScope:inprog 错误的方法是了解哪些代码在摘要循环内运行,哪些代码不运行。

      【讨论】:

        【解决方案3】:
                 $rootScope.refresh = function () {
        
                    $log.info("fired");
                    eventService.events();
                    $timeout(function(){
                        $scope.$apply();
                    })
                 }
        

        【讨论】:

          【解决方案4】:

          因此,强制刷新网格并消除错误的唯一一种方法是删除范围变量并重新设置它,@ectus 说不需要在刷新函数中触发 $scope.$apply 是正确的。 我的工作代码看起来像

                 $rootScope.refresh = function () {
                      $log.info("fired");
                      $scope.initialData = [];
                      getData(urlData);
          

          可能有丑陋的方式,但再次重复只有一种方式如何强制刷新网格。

          【讨论】:

          • 没有必要做delete $scope.initialData$scope.initialData = [] 覆盖它。