2

I understand that you can use track by expr to specify how items are keyed in a ng-repeat directive.

But without track by, how does AngularJS identify items?

Could I control how objects are tracked by altering the object, without using track by, for example?

From the docs:

If no tracking function is specified the ng-repeat associates elements by identity in the collection.

But this is not clear. What does "identity in the collection" mean?

tenfour
  • 36,141
  • 15
  • 83
  • 142
  • 2
    afaik the default is: it injects an expando property - $$hashKey - into your JavaScript objects take a look at http://www.bennadel.com/blog/2556-using-track-by-with-ngrepeat-in-angularjs-1-2.htm – Whisher Oct 30 '14 at 12:40

3 Answers3

3

If you omit the track by expression, then angular by default will track by $$hashkey which is automatically inserted by angular to your list of objects. $$hashkey is refer to as identity of collection.

You can find more here What is the $$hashKey added to my JSON.stringify result

Community
  • 1
  • 1
Rahil Wazir
  • 10,007
  • 11
  • 42
  • 64
  • 1
    Thank you for the link. I also see that [$$hashkey can even be a function](https://github.com/angular/angular.js/blob/f2b7fffdc0b0ad80cebb24f5fea743e9e4a439d5/src/apis.js#L21). – tenfour Oct 30 '14 at 12:47
  • 1
    @tenfour http://stackoverflow.com/questions/26381247/angularjs-is-hashkey-a-reliable-key/26382609 – mccainz Oct 30 '14 at 13:07
2

If the repeat is performed on object keys then the tracking identifier is the key

e.g. ng-repeat="(key,value) in thingies"

For an array the tracking identifier is determined by calling the hashKey function for each array item. The comments from the hashKey function indicates how this is determined:

  • string is string
  • number is number as string
  • object is either result of calling $$hashKey function on the object or uniquely generated id,
  • that is also assigned to the $$hashKey property of the object.
Gruff Bunny
  • 27,738
  • 10
  • 72
  • 59
1

Without a track expression a hash based on the value is computed. WIth a track expression you can supply your own function to compute the hash if you want that level of control.

<!DOCTYPE html>
<html>

  <head>
    <script data-require="angular.js@*" data-semver="1.3.0" src="//code.angularjs.org/1.3.0/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-controller="myCtrl">
    <h1>User Defined Indexer</h1>
    <ul>
      <li ng-repeat="item in data track by getTracker()">{{item}}</li>
    </ul>

    <script>
      var app=angular.module("app",[]);
      app.controller("myCtrl",function($scope){
        $scope.data=[1,2,3,4,5]
        $scope.getTracker = function(v){
          return Math.random();
        }
      });
      angular.bootstrap(document,["app"]);
    </script>

  </body>

</html>
mccainz
  • 3,478
  • 5
  • 35
  • 45
  • Would it be possible to supply my own hash directly from the object, without having to use `track by`? I basically want my HTML templates to not need to know how to identify an object every time it appears in a `ng-repeat` – tenfour Oct 30 '14 at 12:40