Works by

Ren's blog

@rennnosuke_rk 技術ブログです

【AngularJS】ng-repeatの要素に一意な識別子を付加する

メモ。

AngularJSのng-repeatによってHTML内の繰り返し要素を生成できますが、

HTML
<div ng-app="myApp">
  <div ng-controller="MyAppCtrl">
    <div ng-repeat="msg in messages">
      <p>{{msg}}</p>
    </div>
  </div>
</div>
JavaScript
let mod = angular.module('myApp',[]);
mod.controller('MyAppCtrl', ['$scope', function($scope){
  $scope.messages = ["hello" , "ng-repeat"];
}]);

要素型を文字列要素にした場合、同一の内容をiterableオブジェクトに格納すると以下のエラーが発生する場合があります。

JavaScript
let mod = angular.module('myApp',[]);
mod.controller('MyAppCtrl', ['$scope', function($scope){
  $scope.messages = ["hello" , "hello"];
}]);
Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: node in tree, Duplicate key: string:hello

ng-repeatでは各要素に識別子を割り当てているが、デフォルトの識別子は$id(msg)の返戻値となるようです。
要素が文字列型の場合、この返戻値が同一値になるため、識別子が重複しエラーとなるようです。

この問題を解決するには、ng-repeatディレクティブに渡す値にtrack by $indexを追加し、
各要素の識別子をインデックスにします。

<div ng-app="myApp">
  <div ng-controller="MyAppCtrl">
    <div ng-repeat="msg in messages track by $index">
      <p>{{msg}}</p>
    </div>
  </div>
</div>

参考

qiita.com