I was recently presented with a bug, where an input field inside a list controlled by a ng-repeat
kept losing focus everytime the data in the scope changed in the background.
The ng-repeat
in question was written like this: ng-repeat="message in messages"
, and we had a service fetching messages
every 10 seconds that did something like: scope.messages = messages
This totally makes sense, and technically there is nothing wrong with it, however, by design, ng-repeat
triggers itself when the data being wathed (in this case messages
) gets replaced with a new array. This "DOM refresh" could make input fields in the list to lose focus, and even worst, this could represent a huge performance hit when dealing with long arrays of data.
The solution? You can now add a track by $index
to your ng-repeat
:
ng-repeat="message in messages" track by $index
By taking this approach, the "repeat watch" now gets updated only when the array changes in its length.
This fix also has the side benefit of increasing your app's performance as the DOM won't get constantly updated in an unnecessary manner.
You can learn more about the track by
feature here: https://docs.angularjs.org/api/ng/directive/ngRepeat