假设我有一个包含5000个对象(带有布尔值)的数组,我必须在模板中ng-repeat
:
$scope.arr = [
{
"value": true
},
{
"value": false
},
{
"value": false
}
//and so on
]
现在,我想基于一个动态变量过滤这个ng-repeated
数组,比如说' show_filter',我在其他地方设置。
如果' show_filter'被设置为全部'我想要显示所有对象。如果它设置为false(布尔值),那么我想显示具有'值'键设置为false。同样适用于' show_filter'设置为true。
所以,有两种方法:
1。构建自定义过滤器:
我会为过滤任务编写一个自定义过滤器,如下所示:
过滤
app.filter('filterArr', function() {
return function(arr, show_filter) {
var filtered_arr = [];
if(show_filter != 'All') { //if show_filter is a boolean value
for(var i = 0; i < arr.length; i++) {
if(arr[i].value == show_filter) {
filtered_arr.push(arr[i]);
}
}
return filtered_arr;
}
else {
return arr; //return the entire array if show_filter is set to 'All'
}
}
})
模板:
obj in arr | filterArr : show_filter
2。在控制器中写一个过滤函数:
过滤
$scope.filterObjects = function(arr) {
var filtered_arr = [];
if($scope.show_filter != 'All') { //if $scope.show_filter is a boolean value
for(var i = 0; i < arr.length; i++) {
if(arr[i].value == $scope.show_filter) {
filtered_arr.push(arr[i]);
}
}
return filtered_arr;
}
else {
return arr; //return the entire array if show_filter is set to 'All'
}
}
模板:
obj in filterObjects(arr)
以上两种方法中的哪一种会更快?我看到每个摘要循环都会执行自定义过滤器代码,而不仅仅是对$scope.show_filter
所做的更改,这让我感到很自豪相信它效率很低。虽然我不确定两种方式之间哪种更快。
答案 0 :(得分:4)
每个摘要周期都会调用这两个函数。这对于第二个功能来说有点明显。每次通话时filterObjects(arr)
的返回值都可能不同。
为什么在每个摘要周期中都会调用过滤器并不是那么明显。文档说明如下:
过滤函数应该是纯函数,这意味着它应该是无状态和幂等的。 Angular依赖于这些属性,仅在函数输入发生变化时才执行过滤器。
因此,如果arr
和show_filter
都没有改变,则不应该调用过滤器,对吧?但这里有一个问题:检测arr
中的变化代价很高。
Angular必须复制数组以将其与当前内容进行比较。即使没有任何改变,每个项目都必须进行比较。如果项目是对象,则必须比较它们的每个属性。直接调用过滤器要便宜得多。这就是当过滤器应用于数组(或对象)时Angular所做的事情。
要加快应用程序的速度,您有两种选择。第一个是仅在必要时过滤数组并将过滤后的数组暴露给ng-repeat
。例如。如果您可以输入要过滤数组的值,则只要该值发生更改,就会过滤该数组。
如果数组和过滤器都没有改变,那么可以使用第二种替代方法(在你的情况下不是这样)。然后你可以使用一次性绑定:
<li ng-repeat="item in ::array | filter">
当您拥有一组固定的商品并希望按名称对其进行排序时,这非常有用,例如在这种情况下,过滤器只会被调用一次。