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

时间:2015-11-21 08:32:36

标签: 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_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所做的更改,这让我感到很自豪相信它效率很低。虽然我不确定两种方式之间哪种更快。

1 个答案:

答案 0 :(得分:4)

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

为什么在每个摘要周期中都会调用过滤器并不是那么明显。文档说明如下:

  

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

因此,如果arrshow_filter都没有改变,则不应该调用过滤器,对吧?但这里有一个问题:检测arr中的变化代价很高。

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

要加快应用程序的速度,您有两种选择。第一个是仅在必要时过滤数组并将过滤后的数组暴露给ng-repeat。例如。如果您可以输入要过滤数组的值,则只要该值发生更改,就会过滤该数组。

如果数组和过滤器都没有改变,那么可以使用第二种替代方法(在你的情况下不是这样)。然后你可以使用一次性绑定:

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

当您拥有一组固定的商品并希望按名称对其进行排序时,这非常有用,例如在这种情况下,过滤器只会被调用一次。