Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular.js change on one item of ng-repeat causing filters on all other items to run

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

like image 939
fxck Avatar asked Apr 22 '13 13:04

fxck


People also ask

Does ng-repeat create a new scope?

Directives that Create Scopes In most cases, directives and scopes interact but do not create new instances of scope. However, some directives, such as ng-controller and ng-repeat, create new child scopes and attach the child scope to the corresponding DOM element.

How do I filter in NG-repeat?

The ng-repeat values can be filtered according to the ng-model in AngularJS by using the value of the input field as an expression in a filter. We can set the ng-model directive on an input field to filter ng-repeat values.

How do I get the index of an element in NG-repeat?

Note: The $index variable is used to get the Index of the Row created by ng-repeat directive. Each row of the HTML Table consists of a Button which has been assigned ng-click directive. The $index variable is passed as parameter to the GetRowIndex function.


1 Answers

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/
like image 88
Langdon Avatar answered Oct 27 '22 00:10

Langdon