web-dev-qa-db-fra.com

"Les doublons dans un répéteur ne sont pas autorisés" sur ng-repeat

J'ai les données json suivantes retournées à partir d'une demande de service:

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

Et j'essaie le code suivant en html pour parcourir ces données:

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

J'obtiens l'erreur suivante lorsque j'exécute le code:

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

Voici le code de mon contrôleur:

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

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

Quelqu'un pourrait-il m'aider à comprendre pourquoi j'obtiens cette erreur?

21
skip

Votre JSON n'est pas valide et devrait être:

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

Assurez-vous également que vous accédez au document au bon niveau, utilisez:

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

Ensuite, cela devrait fonctionner. Voir ceci JSBin .

11
Goodzilla

Ajouter track by $index à votre ng répéter donc au lieu de:

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

Essayer:

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

Il y a plus d'informations à ce sujet dans la documentation de ce message d'erreur :

Se produit s'il y a des clés en double dans une expression ngRepeat. Les clés en double sont interdites car AngularJS utilise des clés pour associer les nœuds DOM aux éléments.

Par défaut, les collections sont indexées par référence, ce qui est souhaitable pour la plupart des modèles courants, mais peut être problématique pour les types primitifs internés (partager les références).

38
Malcr001

Si je peux ajouter une raison supplémentaire expliquant pourquoi cela peut se produire ...

Si vous faites cela avec un objet JS [] ou {}

et vous le transmettez à une directive comme celle-ci

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

Dans la directive, vous devez transformer myObject en objet en faisant ceci

...
controller: function( $scope ){

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

Ensuite, le HTML et ng-repeat fonctionneront

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

ngRepeat ne sait pas répéter sur une seule chaîne.

Voici à quoi ressemblerait l'objet avant $ scope. $ Eval

"[{ hello: 'you' }]"

et après $ scope. $ eval ()

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

Le type d'erreur fait une référence qu'il ne peut pas répéter d'une chaîne. Voici l'erreur que j'ai eue.

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

7
SoEzPz

Il semble que vous ayez un problème avec la structure des données dans votre portée. Votre exemple JSON montre un objet avec une propriété entries et une propriété count. Vous placez ensuite cet objet entier dans votre portée en tant que entries. Cela signifie que vous devez accéder aux entrées en tant que entries.entries, avec le nombre dans entries.count. Peut-être que ce contrôleur est plus proche de ce que vous vouliez:

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