Javascript 过滤对象数组时的无限$digest循环

Javascript 过滤对象数组时的无限$digest循环,javascript,angularjs,angularjs-digest,Javascript,Angularjs,Angularjs Digest,将参数传递给在$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> &

将参数传递给在$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>
过滤器:

.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;
    };
})
.filter('myFilter',function(){
返回函数(项目、字段、反向){
项目.排序(功能(a,b){
var aValue=a[field]。$t.toLowerCase();
var bValue=b[field]。$t.toLowerCase();
如果(反向)
{
返回((aValue>bValue)-1:((aValueb值)?1:0);
}
});
退货项目;
};
})
如果我像这样运行代码,我将得到$digest循环错误,但是输出将被排序。如果我不使用$scope.Field和$scope.Reverse,而是写入myFilter:'published':true,则它将在没有错误的情况下工作。我检查了所有其他内容,禁用了所有指令和其他可能会干扰同一问题的内容


有人对此有什么好的建议吗

经过一番修补,我终于想出了这个办法。问题是数组和javascript中的所有数组一样,都是通过引用传递的。因此,当过滤器触发传递给array.sort()的函数时,它将触发数组的观察者

因此,通过制作数组的浅层副本,对其进行排序,然后返回,我们可以绕过这个问题。我还添加了带下划线的memoize缓存以加快速度

使用以下三个示例创建了一个Plunker:


你能展示一下AlbumListService.GoogleList中的内容吗?据我所知,每个过滤器都会返回对象的新实例,angular认为这是一个变化,因此会启动新的摘要周期。我已经搜索了几个小时了。非常感谢。
.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;
    };
})