web-dev-qa-db-ja.com

ng-repeatの「リピーターでの複製は許可されていません」

サービスリクエストから次のJSONデータが返されました。

{
    "entries": [{
        "id": 2081,
        "name": "BM",
        "niceName": "bodmas"
        }]
    }, {
        "id": 8029,
        "name": "Mas",
        "niceName": "Masm"
        }]
    }],
    "count": 2
}

そして、私はこのデータをループするためにhtmlで次のコードを試しています:

<option ng-repeat="entry in entries" value="{{entry.name}}">{{entry.name}}</option>

コードを実行すると、次のエラーが表示されます。

Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: entry in entries, Duplicate key: string:c

コントローラーのコードは次のとおりです。

myApp.controller("MyController", ['$scope', '$http', '$log', function($scope, $http, $log){
       ...

       $http.get('https://myServiceURL').success(function(data){
                    $scope.entries = data;
        });
}]);

なぜそのエラーが発生するのかを誰かが理解するのを手伝ってもらえますか?

21
skip

JSONは無効です。

{
    "entries": [{
        "id": 2081,
        "name": "BM",
        "niceName": "bodmas"
    }, {
        "id": 8029,
        "name": "Mas",
        "niceName": "Masm"
    }],
    "count": 2
}

また、適切なレベルでドキュメントにアクセスしていることを確認してください:

$http.get('https://myServiceURL').success(function(data){
    $scope.entries = data.entries;
});

その後、動作するはずです。こちらをご覧ください JSBin

11
Goodzilla

次の代わりにtrack by $indexをng繰り返しに追加します。

<option ng-repeat="entry in entries" value="{{entry.name}}">{{entry.name}}</option>

試してください:

<option ng-repeat="entry in entries track by $index" value="{{entry.name}}">{{entry.name}}</option>

これについての詳細は このエラーメッセージのドキュメント にあります。

NgRepeat式に重複キーがある場合に発生します。 AngularJSはキーを使用してDOMノードをアイテムに関連付けるため、重複キーは禁止されています。

デフォルトでは、コレクションは参照によってキー設定されますが、これはほとんどの一般的なモデルに適していますが、インターンされたプリミティブ型(参照の共有)には問題がある場合があります。

38
Malcr001

これが発生する理由について追加の理由を追加できる場合...

JSオブジェクト[]または{}でこれを行う場合

そして、あなたはこのようなディレクティブにそれを渡している

<my-directive my-attribute="{{ myObject }}"></my-directive>

ディレクティブ内で、これを実行してmyObjectをオブジェクトに戻す必要があります

...
controller: function( $scope ){

  $scope.links = $scope.$eval( $scope.myObject );
....

その後、HTMLとng-repeatが機能します

...
<span class="" ng-repeat="link in links">
...

ngRepeatは、単一の文字列で繰り返す方法を知りません。

以下は、$ scope。$ evalの前のオブジェクトの外観です。

"[{ hello: 'you' }]"

および$ scope。$ eval()の後

[{ hello: 'you' }] an actual object to repeat over.

エラーの種類は、文字列を繰り返すことができない参照を作成します。ここに私が得たエラーがあります。

エラー:[ngRepeat:dupes] http://errors.angularjs.org/1.3.0-beta.8/ngRepeat/dupes?p0=link%20in%20links&p1=string%3Al

7
SoEzPz

スコープ内のデータの構造に問題があるようです。サンプルJSONは、entriesプロパティとcountプロパティを持つオブジェクトを示しています。次に、そのオブジェクト全体をentriesとしてスコープに入れます。これは、entries.entriesのカウントで、entries.countとしてエントリにアクセスする必要があることを意味します。おそらく、このコントローラーはあなたが望んでいたものに近いでしょう:

myApp.controller("MyController", ['$scope', '$http', '$log', function($scope, $http, $log){
    ...

    $http.get('https://myServiceURL').success(function(data){
        $scope.entries = data.entries;
        $scope.count = data.count;
    });
}]);
1
Martin Atkins