AngularJS Filter在创建新数组时会引发infdig错误

时间:2015-03-18 07:47:19

标签: angularjs angularjs-filter angularjs-infdig

我准备把头撞到墙上。我以为我了解角度是如何工作的(过滤器也是如此)。但我无法找到有关我的过滤器的问题。它导致infdig。我甚至不会在过滤器中更改源数组。

(function () {

angular.module('project.filters').filter('splitListFilter', function () {
    return function (data, chunk) {
        if(!data || data.length === 0){
            return data;
        }

        var resultArray = [];
        for (var i = 0, j = data.length; i < j; i += chunk) {
            resultArray.push(data.slice(i, i + chunk));
        }

        return resultArray;
    };
});

})();

我有列表,我需要将数据拆分为x列。用limitTo来解决它很复杂。

(limitTo: $index*x | limitTo: $last ? -z : -x)

它会导致脏模板文件。所以我决定创建一个将数组拆分为组的过滤器。

[1,2,3,4,5,6,7,8] -> [[1,2,3],[4,5,6],[7,8]]

所以我可以在我的模板中轻松使用它。

你可以帮助我解决导致这个过滤器中infdig的原因吗?

编辑:错误消息本身看起来很奇怪,其中一些数字不出现在代码中的任何位置,可以在http://plnkr.co/edit/pV1gkp0o5KeimwPlEMlF

看到
  

达到10 $ digest()次迭代。中止!   观察者在最后5次迭代中被解雇:[[{“msg”:“fn:regularInterceptedExpression”,“newVal”:23,“oldVal”:20}],[{“msg”:“fn:regularInterceptedExpression”,“newVal” :26,“oldVal”:23}],[{“msg”:“fn:regularInterceptedExpression”,“newVal”:29,“oldVal”:26}],[{“msg”:“fn:regularInterceptedExpression”,“ newVal“:32,”oldVal“:29}],[{”msg“:”fn:regularInterceptedExpression“,”newVal“:35,”oldVal“:32}]]

HTML模板

<div class="row" ng-repeat="chunk in docProfile.SysMedicalInterests | splitListFilter: 3">
    <div class="col-md-4" ng-repeat="medInterest in chunk">
        <label style="font-weight:normal;">
        <input type="checkbox" value="{{medInterest.ID}}" ng-click="docProfile.saveInterest(medInterest.ID)" ng-checked="docProfile.isMedChecked(medInterest.ID)"> {{medInterest.Name}}
        </label>
     </div>
</div>

控制器代码

var me = this;
me['SysMedicalInterests'] = null;

    var loadMedicalInterests = function(){
        var postData = { 'Data': me['data']['subData'] };
        return docService.loadMedicalInterests(postData).then(function(resp)      {
            me['SysMedicalInterests'] = resp['data'];
        }, function(){});
    };

loadMedicalInterests();

所以数组以空引用开始,并从服务器加载数据。更改数组会导致第二次过滤运行。但它之后并没有停止

编辑:这里是plunkr http://plnkr.co/edit/OmHQ62VgiCXeVzKa5qjz?p=preview

编辑:关于https://stackoverflow.com/a/21653981/1666060的相关答案,但这仍然没有解释内置过滤器的角度。

这里是angularjs limitTo过滤源代码

https://github.com/angular/angular.js/blob/master/src/ng/filter/limitTo.js#L3

2 个答案:

答案 0 :(得分:2)

关于究竟是什么导致它,我怀疑是这样的事实,即每次运行过滤器时都会创建并返回一个新的数组引用。但是,Angular的内置filter过滤器做同样的事情,所以我不确定出了什么问题。这可能与它正在返回的数组数组有关。

我提出的最好的解决方法/黑客,手动缓存数组引用作为添加属性,我在数组上称为$$splitListFilter,只有在测试失败时才更改它在angular.equals上,在过滤器中计算出正确的结果:

app.filter('splitListFilter', function () {
    return function (data, chunk) {
        if(!data || data.length === 0){
            return data;
        }

        var results = [];
        for (var i = 0, j = data.length; i < j; i += chunk) {
          results.push(data.slice(i, i + chunk));
        }

        if (!data.$$splitListFilter || !angular.equals(data.$$splitListFilter, results)) {
          data.$$splitListFilter = results;
        }
        return data.$$splitListFilter;
    };
});

您可以在http://plnkr.co/edit/vvVJcyDxsp8uoFOinX3V

看到这种情况

答案使用Angular 1.3.15

答案 1 :(得分:0)

JS小提琴正常工作:http://jsfiddle.net/3tzapfhh/1/

也许您错误地使用过滤器。

<body ng-app='app'>
  <div ng-controller='ctrl'>
    {{arr | splitListFilter:3}}
  </div>  
</body>