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

时间:2015-09-23 14:52:02

标签: angularjs angular-digest

这是架构:我有一个控制器和一个服务。控制器可以调用服务并对其数据进行排序。我有一个服务方法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;
});
&#13;
<!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>
&#13;
&#13;
&#13;

重现infdig错误:

  1. 打开控制台。
  2. 点击切换排序。
  3. 导致无限摘要发生的原因是什么?

1 个答案:

答案 0 :(得分:1)

您正在观看的dataSvc.getData()功能每次都会返回一个不同的对象。 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">
相关问题