控制器性能比较中的自定义过滤器与过滤器功能

Custom filter vs filter function in controller performance comparison

本文关键字:过滤器 自定义 功能 性能 性能比 比较 控制器      更新时间:2023-09-26

假设我有一个5000个对象的数组(带有布尔值),我必须在模板中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.构建自定义过滤器:

我会为过滤任务编写一个自定义过滤器,如下所示:

过滤器:

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所做的更改,这让我相信它效率很低。尽管我不确定这两种方式中哪一种更快。

这两个函数都将在每个摘要周期中调用。这对于第二个函数来说有些明显。filterObjects(arr)的返回值在每次调用时可能不同。

为什么在每个摘要周期中都会调用过滤器,这一点并不明显。文件说明如下:

filter函数应该是一个纯函数,这意味着它应该是无状态的和幂等的。Angular依赖于这些属性,并且仅当函数的输入发生变化时才执行过滤器。

所以,如果arrshow_filter都没有改变,那么就不应该调用过滤器,对吧?但问题是:检测arr的变化代价高昂。

Angular必须复制数组以将其与当前内容进行比较。即使什么都没有改变,每一项都必须进行比较。如果这些项是对象,则必须对它们的每个属性进行比较。直接调用过滤器要便宜得多。当过滤器应用于数组(或对象)时,Angular就是这样做的。

要加快应用程序的速度,您有两种选择。第一种方法是仅在必要时对数组进行过滤,并将过滤后的数组暴露给ng-repeat。例如,如果您可以输入一个值来过滤数组,那么只要该值发生变化,就对数组进行过滤。

如果数组和过滤器都没有改变(所以在您的情况下不会改变),则可以使用第二种选择。然后您可以使用一次性绑定:

<li ng-repeat="item in ::array | filter">

当你有一组固定的项目并想按名称排序时,这很有用。例如,在这种情况下,过滤器只会被调用一次。