Javascript 控制器性能比较中的自定义过滤器与过滤器功能
假设我有一个5000个对象(带有布尔值)的数组,我必须在模板中Javascript 控制器性能比较中的自定义过滤器与过滤器功能,javascript,angularjs,performance,filter,angularjs-filter,Javascript,Angularjs,Performance,Filter,Angularjs Filter,假设我有一个5000个对象(带有布尔值)的数组,我必须在模板中ng repeat: $scope.arr = [ { "value": true }, { "value": false }, { "value": false } //and so on ] 现在,我想根据一个动态变量过滤这个ng repeated数组,比如'show_filter',我正在别处设置它 如果“show_filt
ng repeat
:
$scope.arr = [
{
"value": true
},
{
"value": false
},
{
"value": false
}
//and so on
]
现在,我想根据一个动态变量过滤这个ng repeated
数组,比如'show_filter',我正在别处设置它
如果“show_filter”设置为“all”,我想显示所有对象。如果设置为false(布尔值),则我希望显示“value”键设置为false的对象。当“show_filter”设置为true时也是如此
因此,有两种方法:
1。构建自定义筛选器:
我会为过滤任务编写一个自定义过滤器,如下所示:
过滤器:
2。在控制器中写入过滤函数:
过滤器:
以上两种方法中哪一种更快?我看到自定义筛选代码每次都会对每个摘要循环执行,而不仅仅是对
$scope.show\u filter
所做的更改,这让我相信它效率很低。虽然我不确定这两种方法之间哪个更快。在每个摘要循环中都会调用这两个函数。对于第二个函数来说,这有点明显。FilterObject(arr)
的返回值在每次调用时都可能不同
为什么在每个摘要周期中都会调用过滤器,这一点并不明显。文件规定如下:
filter函数应该是纯函数,这意味着它应该是无状态的幂等函数。Angular依赖于这些属性,仅当函数的输入更改时才执行过滤器
因此,如果arr
或show\u filter
都未更改,则不应调用过滤器,对吗?但这里有一个陷阱:检测arr
中的变化代价高昂
Angular必须复制数组以将其与当前内容进行比较。即使没有任何变化,也必须对每一项进行比较。如果项目是对象,则必须对其每个属性进行比较。直接调用过滤器要便宜得多。这就是Angular在对数组(或对象)应用过滤器时所做的
要加速应用程序,您有两个选择。第一种方法是仅在必要时过滤数组,并将过滤后的数组公开给ng repeat
。例如,如果您可以输入一个用于过滤数组的值,则在该值更改时过滤数组
如果阵列和过滤器都不改变(因此在您的情况下不改变),则可以使用第二种选择。然后可以使用一次性绑定:
<li ng-repeat="item in ::array | filter">
当您有一组固定的项目,并希望按名称对其进行排序时,这非常有用,例如,在这种情况下,只会调用一次筛选器。您有两个相同的函数,您会询问哪一个最快?如果您的意思是调用次数最少,那么您可能已经回答了自己的问题?我不知道第二个函数调用了多少次。最快的方法是将过滤后的数组公开给
ngRepeat
。第二个函数必须在每个摘要周期中调用。数组根据外部变量进行过滤,外部变量可以通过事件随时设置。所以,我不认为我可以有一个预过滤数组。我认为最好的方法是对外部变量应用一个watch,并在watch的回调中过滤数组。你觉得呢?这就是我的意思。直接调用过滤器要便宜得多。这是指第一种方法还是第二种方法?此外,一次修正后,过滤器不能应用于对象。尽管如此,谢谢你澄清了很多事情!这适用于自定义过滤器(第一种方法)。过滤器可以应用于任何东西。想想date
过滤器(日期是一个对象),或者json
过滤器,它们只对对象有意义。顺便说一句,数组也是一个对象。
obj in arr | filterArr : show_filter
$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)
<li ng-repeat="item in ::array | filter">