486 votes

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

Je définis un filtre personnalisé comme suit :

<div class="idea item" ng-repeat="item in items" isoatom>    
    <div class="section comment clearfix" ng-repeat="comment in item.comments | range:1:2">
        ....
    </div>
</div>

Comme vous pouvez le voir, le ng-repeat dans lequel le filtre est utilisé est imbriqué dans un autre ng-repeat

Le filtre est défini comme suit :

myapp.filter('range', function() {
    return function(input, min, max) {
        min = parseInt(min); //Make string input int
        max = parseInt(max);
        for (var i=min; i<max; i++)
            input.push(i);
        return input;
    };
});

Je reçois :

Erreur : Les doublons dans un répéteur ne sont pas autorisés. Repeater : comment in item.comments | range:1:2 ngRepeatAction@ https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/an

973voto

Webnet Points 12671

La solution est décrite ici : http://www.anujgakhar.com/2013/06/15/duplicates-in-a-repeater-are-not-allowed-in-angularjs/

AngularJS n'autorise pas les doublons dans une directive ng-repeat. Cela signifie que si vous essayez de faire ce qui suit, vous obtiendrez une erreur.

// This code throws the error "Duplicates in a repeater are not allowed.
// Repeater: row in [1,1,1] key: number:1"
<div ng-repeat="row in [1,1,1]">

Toutefois, il suffit de modifier légèrement le code ci-dessus pour définir un index permettant de déterminer l'unicité, comme indiqué ci-dessous, pour que le système fonctionne à nouveau.

// This will work
<div ng-repeat="row in [1,1,1] track by $index">

Les documents officiels sont ici : https://docs.angularjs.org/error/ngRepeat/dupes

48 votes

Je voulais mentionner que vous pouvez appliquer n'importe quelle propriété de suivi personnalisée pour définir l'unicité, et pas seulement $index. Puisque dans ce scénario les objets n'ont pas d'autres propriétés, cela fonctionne bien. La raison pour laquelle cette erreur se produit est qu'angular utilise un dictionnaire pour stocker l'identifiant d'un élément en tant que clé avec la valeur en tant que référence DOM. D'après le code (ligne 15402 dans angular.js), il semble qu'ils mettent en cache les éléments du DOM précédemment trouvés en se basant sur leur clé afin d'optimiser les performances. Puisqu'ils ont besoin de clés uniques, ils lancent explicitement cette erreur lorsqu'ils trouvent des clés dupliquées à la ligne 15417

16 votes

<div ng-repeat="row in [1,1,1,2,2] |filter: 2 track by $index" > le "filtre de recherche" doit être placé avant "track by $index"

21 votes

Quelle conception inutilement méchante de la part d'Angular. Il serait très, très facile de ne pas voir ce problème pendant le développement et les tests parce que votre tableau ne contient jamais de doublons, pour ensuite voir votre application exploser en production lorsqu'elle est exposée à des doublons pour la première fois. J'ai déjà construit des applications Angular sans connaître la restriction "no dupes" ; je me retrouve maintenant à y repenser et à me demander si je n'ai pas, sans le savoir, créé un code défectueux.

47voto

usefulBee Points 492

Pour ceux qui s'attendent à recevoir du JSON et qui obtiennent toujours la même erreur, assurez-vous d'analyser vos données :

$scope.customers = JSON.parse(data)

12voto

Mahima Agrawal Points 523

J'avais un problème dans mon projet où j'utilisais ng-repeat track by $index mais les produits n'étaient pas reflétés lorsque les données provenaient de la base de données. Mon code est le suivant :

<div ng-repeat="product in productList.productList track by $index">
  <product info="product"></product>
 </div>

Dans le code ci-dessus, product est une directive séparée pour afficher le produit. Mais j'ai appris que $index cause des problèmes lorsque nous passons des données hors du champ d'application. Ainsi, les pertes de données et le DOM ne peuvent pas être mis à jour.

J'ai trouvé la solution en utilisant product.id comme clé dans ng-repeat comme ci-dessous :

<div ng-repeat="product in productList.productList track by product.id">
  <product info="product"></product>
 </div>

Mais le code ci-dessus échoue à nouveau et génère l'erreur suivante lorsque plusieurs produits ont le même numéro d'identification :

angular.js:11706 Erreur : [ngRepeat:dupes] Les doublons dans un répéteur ne sont pas autorisés. Utilisez l'expression 'track by' pour spécifier des clés uniques. Répéteur

J'ai donc finalement résolu le problème en créant une clé unique dynamique pour ng-repeat comme ci-dessous :

<div ng-repeat="product in productList.productList track by (product.id + $index)">
  <product info="product"></product>
 </div>

Cela a résolu mon problème et j'espère que cela vous aidera à l'avenir.

6voto

Ezekiel Victor Points 2512

Quelle est l'utilité de votre filtre "gamme" ?

Voici un exemple de ce que j'ai penser que vous essayez de faire : http://jsfiddle.net/evictor/hz4Ep/

HTML :

<div ng-app="manyminds" ng-controller="MainCtrl">
  <div class="idea item" ng-repeat="item in items" isoatom>    
    Item {{$index}}
    <div class="section comment clearfix" ng-repeat="comment in item.comments | range:1:2">
      Comment {{$index}}
      {{comment}}
    </div>
  </div>
</div>

JS :

angular.module('manyminds', [], function() {}).filter('range', function() {
    return function(input, min, max) {
        var range = [];
        min = parseInt(min); //Make string input int
        max = parseInt(max);
        for (var i=min; i<=max; i++)
            input[i] && range.push(input[i]);
        return range;
    };
});

function MainCtrl($scope)
{
    $scope.items = [
        {
            comments: [
                'comment 0 in item 0',
                'comment 1 in item 0'
            ]
        },
        {
            comments: [
                'comment 0 in item 1',
                'comment 1 in item 1',
                'comment 2 in item 1',
                'comment 3 in item 1'
            ]
        }
    ];
}

1voto

CR Rollyson Points 1311

Si par hasard cette erreur se produit lorsque vous travaillez avec SharePoint 2010 : Renommez les extensions de vos fichiers .json et veillez à mettre à jour le chemin d'accès à restService. Aucun "track by $index" supplémentaire n'a été nécessaire.

Heureusement, on m'a transmis ceci lien à ce raisonnement :

.json devient un type de fichier important dans SP2010. SP2010 inclut certains points de terminaison de services web. L'emplacement de ces fichiers est 14hive \isapi dossier. L'extension de ces fichiers est .json. C'est la raison pour laquelle il y a une telle erreur.

"se préoccupe uniquement du fait que le contenu d'un fichier json est json - pas de son extension de fichier"

Une fois les extensions de fichiers modifiées, tout devrait être prêt.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X