初始情况
快速阅读
我想使用自定义的 AngularJS 过滤器过滤嵌套数组。不幸的是,不仅是 ng-repeat 的数据被过滤,$scope 中的原始对象也被过滤了。
我为您准备了一个小的演示代码:http://jsfiddle.net/7XRB2/
例如,请搜索 Test
,列表将会变短。删除搜索内容,您会看到发生了什么:什么也没有发生。该过滤器并没有过滤 列表,它过滤的是 原始数据!
这是我的过滤器:
app.filter('searchFilter', function() {
return function(areas, searchTerm) {
if (!angular.isUndefined(areas)
&& !angular.isUndefined(searchTerm)) {
var searchExp;
searchExp = new RegExp(searchTerm, 'gi');
var tmpAreas = [];
angular.forEach(areas, function(area) {
var tmpTopics = [];
angular.forEach(area.topics, function(topic) {
var tmpVideos = [];
angular.forEach(topic.videos, function(video) {
if (video.title.match(searchExp)) {
tmpVideos.push(video);
}
});
topic.videos = tmpVideos;
if (topic.videos.length > 0 || topic.title.match(searchExp)) {
tmpTopics.push(topic);
}
});
area.topics = tmpTopics;
if (area.topics.length > 0) {
tmpAreas.push(area);
}
});
return tmpAreas;
}
else {
return areas;
}
}
});
我已经实现了另一个自定义搜索过滤器,它运行良好且没有这个问题:
app.filter('mainNavigationFilter', function () {
return function (elements, selectedElement) {
if (!angular.isUndefined(elements) && !angular.isUndefined(selectedElement) && selectedElement.length > 0) {
var tempElements = [];
angular.forEach(selectedElement, function (id) {
angular.forEach(elements, function (element) {
if(angular.equals(element.id, id)
tempElements.push(element);
}
});
});
return tempElements;
}
else {
elements
}
}
});
我认为的问题
在我的过滤器中,我使用了topic.videos = tmpVideos;
和area.topics = tmpTopics;
。由于 JavaScript 对象引用的原因,我猜想这些新赋值会被继承到原始对象 - 我的作用域对象。
经过一番研究,我找到了angular.copy()
并在我的过滤器中添加了以下代码块:
var cpAreas;
cpAreas = angular.copy(areas);
此外,我将第一个angular.forEach
更改为
angular.foreach(cpAreas, function(area) {[...]});
这里有一个更新的fiddle:http://jsfiddle.net/dTA9k/
无限$digest循环
太好了! 过滤器按预期工作 - 除非你打开控制台...
现在,过滤器引起了一个新问题:
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [...]
我在SO上发现了一些关于这个错误的问题,看起来是由于angular.copy
每次返回一个新对象导致的。
你有什么想法可以解决这个问题吗?