AngularJS 过滤器在创建新数组时抛出 infdig 错误
AngularJS Filter throws infdig error when it creates new array
我快要用头撞墙了。我以为我了解 angular 是如何工作的(还有过滤器)。但我就是找不到关于我的过滤器的问题。它会导致 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]]
所以我可以很容易地在我的模板中使用它。
你能帮我看看是什么原因导致这个过滤器出现故障吗?
编辑:错误消息本身看起来很奇怪,其中一些数字没有出现在代码中的任何地方,可以在 http://plnkr.co/edit/pV1gkp0o5KeimwPlEMlF
中看到
10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [[{"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
编辑:关于 的相关答案,但这仍然不能解释 angular 内置过滤器。
这里是angularjs limitTo过滤源码
https://github.com/angular/angular.js/blob/master/src/ng/filter/limitTo.js#L3
JS fiddle 工作正常:http://jsfiddle.net/3tzapfhh/1/
可能是你滤镜用错了
<body ng-app='app'>
<div ng-controller='ctrl'>
{{arr | splitListFilter:3}}
</div>
</body>
关于它的确切原因,我怀疑与以下事实有关:每次 运行 过滤器都会创建并返回一个新的数组引用。但是,Angular 的内置 filter
过滤器做同样的事情,所以我不确定哪里出了问题。这可能与返回的数组数组有关。
我想出的最好的方法是 workaround/hack,手动缓存数组引用作为添加的 属性,我在数组上称之为 $$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
看到这个工作
答案使用Angular1.3.15
我快要用头撞墙了。我以为我了解 angular 是如何工作的(还有过滤器)。但我就是找不到关于我的过滤器的问题。它会导致 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]]
所以我可以很容易地在我的模板中使用它。
你能帮我看看是什么原因导致这个过滤器出现故障吗?
编辑:错误消息本身看起来很奇怪,其中一些数字没有出现在代码中的任何地方,可以在 http://plnkr.co/edit/pV1gkp0o5KeimwPlEMlF
中看到10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations: [[{"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
编辑:关于 的相关答案,但这仍然不能解释 angular 内置过滤器。
这里是angularjs limitTo过滤源码
https://github.com/angular/angular.js/blob/master/src/ng/filter/limitTo.js#L3
JS fiddle 工作正常:http://jsfiddle.net/3tzapfhh/1/
可能是你滤镜用错了
<body ng-app='app'>
<div ng-controller='ctrl'>
{{arr | splitListFilter:3}}
</div>
</body>
关于它的确切原因,我怀疑与以下事实有关:每次 运行 过滤器都会创建并返回一个新的数组引用。但是,Angular 的内置 filter
过滤器做同样的事情,所以我不确定哪里出了问题。这可能与返回的数组数组有关。
我想出的最好的方法是 workaround/hack,手动缓存数组引用作为添加的 属性,我在数组上称之为 $$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
看到这个工作答案使用Angular1.3.15