8

I'm still running into the same problem, filters and functions inside ng-repeat being called all the damn time.

Example here, http://plnkr.co/edit/G8INkfGZxMgTvPAftJ91?p=preview, anytime you change something on a single row, someFilter filter is called 1000 times.

Apparently it's because any change on a child scope bubbles up to its parent, causing $digest to run, causing all filters to run(https://stackoverflow.com/a/15936362/301596). Is that right? How can I prevent it from happening in my particular case?

How can I make it run only on the item that has changed?

In my actual use case the filter is called even when the change is not even on the items of ng-repeat, it's so pointless and it is actually causing performance problems..

// edit cleared all the unnecessary stuff from the plunker http://plnkr.co/edit/G8INkfGZxMgTvPAftJ91?p=preview

Community
  • 1
  • 1
fxck
  • 4,898
  • 8
  • 56
  • 94

1 Answers1

4

This is just how Angular's dirty checking works. If you have an array of 500 items and the array changes, the filter must be reapplied to the entire array. And now you're wondering "why twice"?

From another answer:

This is normal, angularjs uses a 'dirty-check' approach, so it need to call all the filters to see if exists any change. After this it detect that have a change on one variable(the one that you typed) and then it execute all filters again to detect if has other changes.

And the answer it references: How does data binding work in AngularJS?

Edit: If you're really noticing sluggishness (which I'm not on an older Core 2 Duo PC), there are probably a number of creative ways you can get around it depending on what your UI is going to be.

  1. You could put the row into edit mode while the user is editing the data to isolate the changes, and sync the model back up when the user gets out of edit mode
  2. You could only update the model onblur instead of onkeypress using a directive, like this: http://jsfiddle.net/langdonx/djtQR/1/
Community
  • 1
  • 1
Langdon
  • 19,875
  • 18
  • 88
  • 107
  • Yeah I read what Misko wrote, I also read how it's not gonna be noticeable even with 2000 items, yet it's very much noticeable. It's serious pain in the ass when all those filters are called anytime I type in anything in the input before the actual ng-repeat(http://plnkr.co/edit/G8INkfGZxMgTvPAftJ91?p=preview), especially when I have multiple filters in each row of ng-repeat. Makes me think it's better to modify the value I need filtered on init and then after change. – fxck Apr 22 '13 at 13:51
  • 1
    i support you on this this it is really painful feature of angular because filters are just for data transformations so they should not be watching every line – Ajay Beniwal Apr 22 '13 at 14:01
  • So the only solution is small collections? – Bart Apr 22 '13 at 14:04
  • @foxx See my Edit. Would those solutions work for what you're trying to do? – Langdon Apr 22 '13 at 15:05
  • Funny enough, I'm already doing both in my actual app, dealing with blur little differently, using what Vojta suggested here https://groups.google.com/forum/?fromgroups=#!topic/angular/LH0Q1A-qTVo but nevertheless, it's still slow, going to and from editing mode causes sluggishness and so in fact does blur, since it's sending ajax post as well as going thru thousands of filters.. – fxck Apr 22 '13 at 15:16
  • also you might not see any sluggishness here, but imagine there are three different filters in each row, doing slightly more expensive stuff than adding "hi" to a string, like formatting seconds to hh:mm:ss and converting start and end dates using momentjs.. it's no huge lag, but it's noticeable and it's annoying.. – fxck Apr 22 '13 at 15:19
  • @foxx I know those things (time format) are client-side concerns, but if you're running into issues, you might as well store the data how it will be displayed. A filter seems like the wrong way to handle it, considering your use case here. Massage the data coming in once, and massage it on blur when you store it back into the scope. – Langdon Apr 22 '13 at 15:34
  • Yeah that's what I said in the first comment. It's a shame though. – fxck Apr 22 '13 at 15:41