2015-11-21 45 views
7

假設我有5000個對象(具有布爾值),我必須ng-repeat在模板的陣列:自定義過濾器VS在控制器的性能比較濾波函數

$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) 

以上哪兩種方法會更快?我已經看到每個digest循環每次都執行自定義過濾器代碼,而不僅僅是對$scope.show_filter所做的更改,這使我相信其效率非常低。雖然我不確定兩種方式之間哪個更快。

+0

你有兩個相同的功能,你問什麼是最快的?如果你的意思是所謂的最少次數,那麼你可能已經回答了你自己的問題了? – davidkonrad

+0

我不知道第二個函數調用了多少次。 –

+0

最快的選擇是將過濾的數組展示給'ngRepeat'。必須在每個摘要循環中調用第二個函數。 – zeroflagL

回答

4

這兩個函數都將在每個摘要循環中調用。對於第二個功能來說這很明顯。每次通話時,返回值filterObjects(arr)可能會有所不同。

爲什麼在每個摘要循環中會調用過濾器並不那麼明顯。該文檔聲明如下:

過濾函數應該是一個純函數,這意味着它應該是無狀態和冪等的。 Angular依賴於這些屬性,並且只有在函數的輸入發生變化時才執行過濾器。

因此,如果既不arrshow_filter改變,那麼過濾器不應該被調用,對吧?但是這裏有一個問題:檢測arr中的變化是很昂貴的。

Angular必須複製數組以將其與當前內容進行比較。即使沒有任何變化,每一個項目都必須進行比較。如果這些項目是對象的每一個屬性都必須進行比較。直接調用過濾器會更便宜。這就是當一個過濾器應用於數組(或對象)時Angular所做的事情。

要加快應用程序,你有兩種選擇。第一種是隻在必要時過濾數組,並將過濾後的數組公開到ng-repeat。例如。如果您可以輸入數組將被過濾的值,那麼只要該值發生更改就過濾該數組。

如果數組和過濾器都不改變,那麼可以使用第二種方法(所以不適用於你的情況)。然後你可以使用一次性的綁定:

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

當你有一個固定的項目,並希望通過名字,例如對它們進行排序這是很有用在這種情況下,過濾器只會被調用一次。

+0

'直接調用過濾器會更便宜'。這是指第一種方法還是第二種?另外,一個修正,過濾器不能應用於一個對象。儘管如此,謝謝你清理了很多東西! –

+0

這適用於自定義過濾器(第一種方法)。一個過濾器可以應用於一切。想想'date'filter(一個日期是一個對象),或者'json'過濾器,它只對對象有意義。數組也是一個對象,順便說一句。 – zeroflagL