过滤对象数组时无限 $digest 循环
Infinite $digest loop when filtering array of objects
将参数传递给在 $scope 上定义的过滤器时,只是 运行 进入无限 $digest 循环。
在HTML中:
<ul id="albumListUL" class="fa-ul">
<li ng-repeat="album in GoogleList | myFilter:Field:Reverse track by album.id.$t">
<i class="fa-li fa fa-google-plus"></i>
<a href="#" id="{{album.gphoto$id.$t}}" class="g_album" alt="{{album.title.$t}}">
{{album.title.$t}} <span class="badge">{{album.gphoto$numphotos.$t}}</span>
</a>
</li>
</ul>
控制器:
.controller("AlbumListController", ['$scope', 'AlbumListService', function($scope, AlbumListService) {
$scope.Field = "published";
$scope.Reverse = true;
$scope.GoogleList = AlbumListService.GoogleList;
}])
过滤器:
.filter('myFilter', function() {
return function(items, field, reverse) {
items.sort(function(a, b){
var aValue = a[field].$t.toLowerCase();
var bValue = b[field].$t.toLowerCase();
if(reverse)
{
return ((aValue > bValue) ? -1 : ((aValue < bValue) ? 1 : 0));
} else {
return ((aValue < bValue) ? -1 : ((aValue > bValue) ? 1 : 0));
}
});
return items;
};
})
如果我 运行 这样的代码,我将得到 $digest 循环错误,但输出将被排序。如果我不使用 $scope.Field 而 $scope.Reverse 写入 myFilter:'published':true 它将正常工作而不会出现错误。我已经检查了其他所有内容,禁用了所有指令和其他可能会干扰相同问题的内容。
有人对此有一些好的意见吗?
经过一番修改,我已经弄明白了。问题是数组是通过引用传递的,就像 javascript 中的所有数组一样。因此,每当过滤器触发传递给 array.sort() 的函数时,它将触发数组的观察者。
因此,通过制作数组的浅表副本、对其进行排序然后返回它,我们可以解决这个问题。我还使用 underscoreJS memoize 添加了缓存以加快速度。
使用以下三个示例创建了一个 Plunker:https://embed.plnkr.co/ul9ZiK/
写了一个关于问题的快速博客 post:http://www.hackviking.com/development/angularjs-digest-loop-when-filtering-array-of-objects/
将参数传递给在 $scope 上定义的过滤器时,只是 运行 进入无限 $digest 循环。
在HTML中:
<ul id="albumListUL" class="fa-ul">
<li ng-repeat="album in GoogleList | myFilter:Field:Reverse track by album.id.$t">
<i class="fa-li fa fa-google-plus"></i>
<a href="#" id="{{album.gphoto$id.$t}}" class="g_album" alt="{{album.title.$t}}">
{{album.title.$t}} <span class="badge">{{album.gphoto$numphotos.$t}}</span>
</a>
</li>
</ul>
控制器:
.controller("AlbumListController", ['$scope', 'AlbumListService', function($scope, AlbumListService) {
$scope.Field = "published";
$scope.Reverse = true;
$scope.GoogleList = AlbumListService.GoogleList;
}])
过滤器:
.filter('myFilter', function() {
return function(items, field, reverse) {
items.sort(function(a, b){
var aValue = a[field].$t.toLowerCase();
var bValue = b[field].$t.toLowerCase();
if(reverse)
{
return ((aValue > bValue) ? -1 : ((aValue < bValue) ? 1 : 0));
} else {
return ((aValue < bValue) ? -1 : ((aValue > bValue) ? 1 : 0));
}
});
return items;
};
})
如果我 运行 这样的代码,我将得到 $digest 循环错误,但输出将被排序。如果我不使用 $scope.Field 而 $scope.Reverse 写入 myFilter:'published':true 它将正常工作而不会出现错误。我已经检查了其他所有内容,禁用了所有指令和其他可能会干扰相同问题的内容。
有人对此有一些好的意见吗?
经过一番修改,我已经弄明白了。问题是数组是通过引用传递的,就像 javascript 中的所有数组一样。因此,每当过滤器触发传递给 array.sort() 的函数时,它将触发数组的观察者。
因此,通过制作数组的浅表副本、对其进行排序然后返回它,我们可以解决这个问题。我还使用 underscoreJS memoize 添加了缓存以加快速度。
使用以下三个示例创建了一个 Plunker:https://embed.plnkr.co/ul9ZiK/
写了一个关于问题的快速博客 post:http://www.hackviking.com/development/angularjs-digest-loop-when-filtering-array-of-objects/