Angular track by optimization and arrays
If you do a search on the web for Angular ng-repeat, you will of course get the documentation for ng-repeat, but you will also find several blog posts about how to optimize ng-repeat by using the track by
option. See http://www.codelord.net/2014/04/15/improving-ng-repeat-performance-with-track-by/, for example. Aviv uses the following example
<ul class="tasks">
<li ng-repeat="task in tasks" ng-class="{done: task.done}">
{{task.id}}: {{task.title}}
</li>
</ul>
Here the code assumes an array of task objects, e.g.
$scope.tasks = [{id: 1, title: "First task"}, ...]
With this code, when tasks
is updated, say a new task is pushed on the end of the array, Angular will deconstruct and completely build the li
elements in the ng-repeat. It would be awesome if angular only updated the modified tasks and the related DOM elements. We can do this with the simple change of
ng-repeat="task in tasks track by $index"
of
ng-repeat="task in tasks track by task.id"
However, track by
can seems like a bug if you are repeating a list like the following [0,0,1,2,3]
and it updated to [0,1,2,3,4]
. In this case, the tracking value, $index
, never changes, so the DOM elements will not be updated. Here is my fix:
ng-repeat="value in arrasy track by array_hash($index, value)"
where
$scope.array_hash = function(index, value) {
return String($index) + '-' + String(value);
}
Now, the track by
value changes for both index and value changes. Of course there are problems here, I am assuming that String(value)
makes sense. You will have to modify as appropriate for your use case.