简体   繁体   中英

AngularJS orderBy same property as ngModel throws $digest error

When I try to orderBy a property that I am binding to in a ng-repeat I get a $digest error. I think it is occurring because in one digest the ng-model value is updating, which effects the parents orderBy clause. I do not know how to get around this.

Plunker (Update)

This shows the issue occurring. Be sure to open the console!

http://embed.plnkr.co/rGLagq/preview

JS

var options = [
    {
        name: 'test',
        isSelected: true
    }, 
    {
        name: 'another test',
        isSelected: false
    }
];

HTML

<div ng-repeat="option in options | orderBy:'-isSelected'">
        <label>
             <input type="checkbox"
                    ng-model="option.isSelected"> {{option.name}}
        </label>
    </div>

Error

Error: [$rootScope:inprog] $digest already in progress

This issue is caused by a bug in angular:

https://github.com/angular/angular.js/issues/10014

Should hopefully be fixed by: https://github.com/angular/angular.js/pull/9808

Target fix version: 1.3.4

Make sure you don't have manual calls like $scope.$apply() or $scope.$digest in your code that will kick off digest cycles manually. The code you are showing here should be ok.

The inprog error occurs sometimes when the you trigger code (such as a DOM event) programmatically (from within Angular), which is normally called by an external trigger. This kind of error is normally complex to handle. Your best bet is to use $timeout to wait for digest to complete and then do your tasks. I've modified your code to provide the intended functionality using $timeout. Please take a look at below code. To know more about issues regarding inprog, see this link

https://docs.angularjs.org/error/ $rootScope/inprog

HTML

<body ng-controller="MainCtrl">
  <div ng-repeat="option in options | orderBy:'-isSelected'">
    <label>
      <input type="checkbox" ng-click="option.selected()"> {{option.name}}
    </label>
  </div>
</body>

JS

var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $timeout) {
    var myScope = $scope;
    myScope.options = [];
    for (var i = 1; i <= 10; i++) {
        myScope.options.push(new function(){
            var myself = this;
            myself.name = 'Tag ' + i;
            myself.isSelected = false;
            myself.selected = function() {
                $timeout(function() {
                    myself.isSelected = !myself.isSelected;
                    myScope.$apply();
                }, 0, false);
            };
        });
    }
}); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM