为什么这种排序会导致无限摘要错误?

Why does this sorting cause an infinite digest error?

架构如下:我有一个控制器和一个服务。控制器可以调用该服务并对它的数据进行排序。我有一个服务方法 setSort,它只是在服务中设置一个变量。控制器监视服务中的数据。如果排序处于活动状态,我会收到无限摘要错误。演示:http://jsbin.com/berujec/edit?js,output

/**
* Angular fast-changing data with sort
*/

console.clear();


angular.module('app', [])

.controller('main', function($scope, dataSvc, $timeout) {
    $scope.items = dataSvc.generateData().getData();
 
 $scope.$watch(dataSvc.getData, function(curr, orig) {
  if(curr !== orig) {
   $scope.items = curr;
  }
 });
 
 var toggle = true;
 $scope.onClick = function() {
  dataSvc.setSort( toggle ? 'asc' : 'desc' );
  toggle = !toggle;
 };
})

.factory('dataSvc', function() {
  
 var data = [];
 var sort;
 var limit = 50;
 
 //use US state names just for fun
 var states = ["alabama", "alaska", "american samoa", "arizona", "arkansas", "california", "colorado", "connecticut", "delaware", "district of columbia", "federated states of micronesia", "florida", "georgia", "guam", "hawaii", "idaho", "illinois", "indiana", "iowa", "kansas", "kentucky", "louisiana", "maine", "marshall islands", "maryland", "massachusetts", "michigan", "minnesota", "mississippi", "missouri", "montana", "nebraska", "nevada", "new hampshire", "new jersey", "new mexico", "new york", "north carolina", "north dakota", "northern mariana islands", "ohio", "oklahoma", "oregon", "palau", "pennsylvania", "puerto rico", "rhode island", "south carolina", "south dakota", "tennessee", "texas", "utah", "vermont", "virgin islands", "virginia", "washington", "west virginia", "wisconsin", "wyoming"];
 
 function generateData(limit) {
  var n = 0;
  var data = [];
  while(n < limit) {
   n++;
   data.push({
    id: states[n], //these are stable, always same
    score: Math.round(100 * Math.random()) //random
   });
  }
  return data;
 }
 
 function sortBy() {
  data = _.sortByOrder(data, ['score'], [sort]);
 }
 
 
 var svc = {
     
  getData: function() {
   if(sort) {
    sortBy(sort);
   }
   return data;
  },
  
  generateData: function() {
   data = generateData(limit);
   return this;
  },
  
  setSort: function(order) {
      sort = order;
   return this;
  }
  
 };

 return svc;
});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<script src="https://cdn.rawgit.com/lodash/lodash/3.10.1/lodash.min.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body ng-app="app">
  <div ng-controller="main">
   <button ng-click="onClick()">Toggle Sort</button>
    <ul>
  <li ng-repeat="item in items track by item.id">
          {{ item.id }}<br>
    {{ item.score }}
  </li>
 </ul>
  </div>
</body>
</html>

重现 infdig 错误:

  1. 打开控制台。
  2. 单击“切换排序”。

是什么原因导致出现无限摘要?

您正在观看的 dataSvc.getData() 函数 returns 每次都是不同的对象。 Angular 将保持 运行 摘要循环,直到它所观察的一切都没有改变。您可以通过删除 $watch 来解决此问题。 http://jsbin.com/fakijiqujo/1/edit?console,output

JS

$scope.getItems = function() {
  return dataSvc.getData();
};

HTML

<li ng-repeat="item in getItems() track by item.id">