1

Like the title says, what is the best approach to filter a list of ng-repeat? To use a custom (or existing) .filter() or to create a custom filter function inside my controller?

The reason why I'm asking it is because the .filter() is called multiple times (everytime there is a dygest cycle according to this answer).

So I'm concerned about performance issue. If I have a huge list to use inside the ng-repeat and need to filter it, isn't it going to take a huge impact when using .filter()?

On the other hand, when using a custom filter function inside a controller I'll only filter the list when it's needed and only once. I have a better control over this part.

Is this a correct logic? Or is there any other way to optimize the use of filters?

Community
  • 1
  • 1
celsomtrindade
  • 4,501
  • 18
  • 61
  • 116

2 Answers2

1

I believe you were asking something like this? (Check log)

https://plnkr.co/edit/B0WSa11DWcCaImEoexVh?p=preview

So like the post you linked (which linked in to a fiddle) it truly fires filters two times inside ng-filter but if you make the sort inside your controller it will only be hit once.

Edit

My suggestion would be that if you have a large object coming in which need to be sorted is:

  1. Back-end sort(if possible)

  2. Sort using a function inside the controller

  3. (Make a custom filter which will skip the filtering on the first go and return the original? :I )

Video explaining about filters: http://www.bennadel.com/blog/2766-stateless-filters-don-t-apply-to-objects-arrays-or-ngrepeat-in-angularjs-1-3.htm

Konkko
  • 662
  • 4
  • 15
  • This is what I had in mind. On the back-end is impossible because it's based on users interaction. If I'll do a request for each time user filter something, it would be worse. I'll try it out with a function within a controller – celsomtrindade Mar 24 '16 at 02:05
  • Yeah thought of that afterwards but for some strange reason ended up putting the back-end into it I'll cross it out – Konkko Mar 24 '16 at 02:10
  • @CelsomTrindade you might be interested in this http://www.bennadel.com/blog/2766-stateless-filters-don-t-apply-to-objects-arrays-or-ngrepeat-in-angularjs-1-3.htm – Konkko Mar 24 '16 at 02:50
  • 1
    The explanation from Ben was awesome... Like always... Now I have no doubts about NOT using a filter .filter(). Thanks! – celsomtrindade Mar 24 '16 at 13:48
0

The best way to actually do that is the build in "directive". As shown(Ill Post multiple examples.) :

app.controller('MainCtrl', function($scope) {
   $scope.Items= [
       { id: 1, color: 'lightblue' },
       { id: 2, color: 'blue' }
   ];
});

div ng-repeat="item in Items| filter: { color: 'blue' }"> 

Or you could do it with

Functions

 app.controller('MainCtrl', function($scope) {
           $scope.friends= [
               { id: 1, name: 'John' },
               { id: 2, name: 'Richard' }
           ];
           $scope.searchText= function (item) { 
               return item === 'John'; 
            }
        });



 <div ng-repeat="friend in friends | filter: searchText">

EDIT2

So for nested arrays...

app.controller('MainCtrl', function($scope) {
               $scope.colors= [
                   {color:['blue','green','red']}
               ];
            });

Then you would do...

<div ng-repeat="color in colors">
  <div ng-repeat="uniqueColor in color">
     {{uniqueColor}}
  </div>
</div>

Here you dont even need a filter.. I like to call this a "nested ng-repeat" :D.

Here is a fiddle for better demonstration..

EDIT3

Now filtering the ng-repeat..

<div ng-repeat="color in colors">
      <div ng-repeat="uniqueColor in color | filter: 'Blue'">
         {{uniqueColor}}
      </div>
    </div>

Fiddle of that represented here..

EDIT4

you can just use as i read:

app.filter("filterName", function(){
  return function(obj){
   return "Apple.inc"
  }
})

Fiddle

amanuel2
  • 4,508
  • 4
  • 36
  • 67
  • Ok. But what if I have a nested array to filter? For example, {color:['blue','green','red']}, and I need to filter based on some checkbox the user selected? Than I'll have to create a more elaborated custom filter, right? – celsomtrindade Mar 24 '16 at 00:30
  • Hmm did my new anwser help @CelsomTrindade ? – amanuel2 Mar 24 '16 at 00:45
  • @Konkko . The problem he adressed me on comment #1 , does not need a filter at all.. I tend to keep life easy, by making the code clean/easy/readble.. So you could just do a nested ng-repeat – amanuel2 Mar 24 '16 at 00:50
  • Not yet. My doubt is not about repeating a nested array, but filtering it by users choice. Let's say i have a huge array and each object has it's own set of colors. Some have 1 color, others have 2, or 3, etc.. But i need to filter the main list based on the colors the users selects from a checkbox list. So if user select 'Blue', I want to filter the list and show only the items with at least the 'Blue' color on it. If he selects 'Blue' and 'Pink', I need to filter it again and show all objects with at least blue or pink color. – celsomtrindade Mar 24 '16 at 00:50
  • Ok @CelsomTrindade edited my anwser for EDIT3 to adress that question – amanuel2 Mar 24 '16 at 00:53
  • Ok @Konkko edited my anwser again for EDIT4 adressing your problem – amanuel2 Mar 24 '16 at 00:54
  • Ok, but keep in min, my doubt is not about how to make the filter, but what scenario would have a better performance on a huge list. Using it from inside a controller or a custom .filter() – celsomtrindade Mar 24 '16 at 00:55
  • Ok so you want a custom filter... I mean if you have a huge Data you will habe to use a .filter(); guess another edit .... :( – amanuel2 Mar 24 '16 at 00:56
  • EDited @CelsomTrindade. But to be honest Im not to sure about custom filters though.. – amanuel2 Mar 24 '16 at 01:16