最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ($rootScope:inprog) $apply already in progress - Stack Overflow

programmeradmin1浏览0评论

I'm trying apply changes to ui grid after refreshing data but getting this error:

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

 .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 pile (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)

What can be wrong? my code below

get data

    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);

get row value by click

     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();
                });
            };

where eventService.singleEvent is

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

display row data as form 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>

submit changes

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

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

update services

 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);
           });
        }

refresh grid

$rootScope.refresh = function () {

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

refresh services

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

in the end I see the error

$apply already in progress

but data has been uploaded to DB and modified. What can be wrong?

I'm trying apply changes to ui grid after refreshing data but getting this error:

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

 http://errors.angularjs/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 pile (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)

What can be wrong? my code below

get data

    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);

get row value by click

     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();
                });
            };

where eventService.singleEvent is

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

display row data as form 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>

submit changes

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

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

update services

 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);
           });
        }

refresh grid

$rootScope.refresh = function () {

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

refresh services

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

in the end I see the error

$apply already in progress

but data has been uploaded to DB and modified. What can be wrong?

Share Improve this question asked Jun 22, 2016 at 17:18 AntonAnton 7964 gold badges14 silver badges35 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 4

FIX 1 -

Use

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

It will be triggered when the digest cycle is pleted.

FIX 2 -

$scope.$$phase will return true if the digest cycle is running else false, but it will not be useful in your case as it doesn't provide any callback function.

Also its not remended to use

$timeout callback runs during digest:

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

There's no need to trigger it inside refresh. It should be

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

The way to avoid $rootScope:inprog errors is to be aware which code runs within digest cycle, and which code doesn't.

         $rootScope.refresh = function () {

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

So the only one way to force refresh grid and take out the error is to delete scope variable and set it again, @ectus was right when said there is no need to trigger $scope.$apply inside refresh function. My working code looks like

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

May be there is ugly way, but repeat again there is only one way how to force refreshing grid.

发布评论

评论列表(0)

  1. 暂无评论