Угловая ошибка ng-repeat «Дубликаты в повторителе не допускаются».

402

Я определяю собственный фильтр следующим образом:

<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>

Как вы можете видеть, ng-repeat, где используется фильтр, вложен в другой ng-repeat

Фильтр определяется следующим образом:

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;
    };
});

Я получаю:

Ошибка: дубликаты в ретрансляторе не допускаются. Повторитель: комментарий в item.comments | диапазон: 1: 2 ngRepeatAction @https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/an

Теги:
ng-repeat

11 ответов

798
Лучший ответ

Решение на самом деле описано здесь: http://www.anujgakhar.com/2013/06/15/duplicates-in-a-repeater-are-not-allowed-in-angularjs/

AngularJS не допускает дубликатов в директиве ng-repeat. Это означает, что если вы пытаетесь сделать следующее, вы получите сообщение об ошибке.

// 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]">

Однако, слегка изменив приведенный выше код, чтобы определить индекс для определения уникальности, как показано ниже, он снова заработает.

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

Официальные документы находятся здесь: https://docs.angularjs.org/error/ngRepeat/dupes

  • 48
    Я хотел бы упомянуть, что вы можете применять любое пользовательское свойство отслеживания для определения уникальности, а не только $ index. Так как в этом сценарии объекты не имеют никаких других свойств, это прекрасно работает. Причина этой ошибки в том, что angular использует словарь для хранения идентификатора элемента в качестве ключа со значением в качестве ссылки DOM. Из кода (строка 15402 в angular.js) похоже, что они кэшируют ранее найденные элементы DOM на основе их ключа в качестве оптимизации производительности. Поскольку им нужны уникальные ключи, они явно выдают эту ошибку, когда находят повторяющиеся ключи в строке 15417.
  • 16
    <div ng-repeat="row in [1,1,1,2,2] |filter: 2 track by $index" > "фильтр поиска" должен быть перед "track by $ index"
Показать ещё 3 комментария
36

Для тех, кто ожидает JSON и по-прежнему получает ту же ошибку, убедитесь, что вы анализируете свои данные:

$scope.customers = JSON.parse(data)
  • 4
    это не работает для меня, я ожидаю, что json, после использования службы $ http, но SyntaxError: неожиданный токен o в Object.parse (нативный)
  • 1
    @Fergus рад, что это работает для вас; однако, убедитесь, что вы ищете разницу между JSON.parse и JSON.stringify, если вы уже не знаете.
Показать ещё 1 комментарий
4

Что вы намерены делать для своего фильтра диапазона?

Вот рабочий пример того, что, я думаю, вы пытаетесь сделать: 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'
            ]
        }
    ];
}
3

У меня возникла проблема в моем проекте, где я использовал ng-repeat track по индексу $index, но продукты не отражались, когда данные поступают из базы данных. Мой код выглядит следующим образом:

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

В приведенном выше коде продукт является отдельной директивой для отображения продукта. Но я узнал, что $index вызывает проблему, когда мы передаем данные из области. Таким образом, потери данных и DOM не могут быть обновлены.

Я нашел решение, используя product.id как ключ в ng-repeat, как показано ниже:

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

Но приведенный выше код снова терпит неудачу и выдает ошибку ниже, когда более одного продукта поставляется с одним и тем же идентификатором:

angular.js: 11706 Ошибка: [ngRepeat: dupes] Дубликаты в ретрансляторе не разрешены. Используйте выражение "track by" для указания уникальных ключей. Ретранслятор

Итак, я решил проблему, создав динамический уникальный ключ ng-repeat, как показано ниже:

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

Это решило мою проблему и надеюсь, что это поможет вам в будущем.

  • 1
    Конечно, track by $index будет лучше, чем track by (product.id + $index) ? С одной стороны, track by $index проще, а с другой стороны, у вас, вероятно, нет никакой гарантии, что значения (product.id + $index) будут уникальными. Например, если ваш массив начинается с продукта с id 5, и после этого существует продукт с id 4, их значения (product.id + $index) будут равны 5 (5 + 0 для первого продукта, 4 +1 за второе) и вы все равно получите дубликаты в повторителе, не допускается ошибка.
  • 1
    Я согласен с тем, что $ index проще, но вышеупомянутое решение работает для меня, чтобы решить все проблемы, с которыми я столкнулся с $ index. И в моем случае product.id является буквенно-цифровым, поэтому (product.id + $ index) ни в коем случае нельзя дублировать. Таким образом, идея этого решения состояла в том, что если $ index вызывает какие-либо проблемы в кейсе, то мы можем использовать любую логику с треком, по которой уникальным образом создается id.
1

Если случайно эта ошибка возникает при работе с SharePoint 2010: переименуйте расширения .json и обязательно обновите свой путь restService. Никакой дополнительной "дорожки по индексу" не требуется.

К счастью, мне было отправлено это ссылка в это обоснование:

.json становится важным типом файла в SP2010. SP2010 включает в себя сертификаты конечных точек webservice. Расположение этих файлов - папка 14hive\isapi. Расширением этих файлов являются .json. Именно по этой причине она дает такую ​​ошибку.

"заботится только о том, что содержимое json файла json - не расширение его файла

После изменения расширений файлов все должно быть установлено.

0

тогда вы извлекаете элементы на основе индекса, тогда вы не получите эту ошибку, добавьте трек по индексу

<li ng-repeat='name in stafflist track by $index'>{{name}}</li>
0

попробуйте это

$http({
        method: 'GET',
        url: url,   // your remote url
        responseType: "json"
    }).
     then(function successCallback(response) {
         //your code when success
    }, function errorCallback(response) {
        //your code when fails
    });
0

На всякий случай это случается с кем-то другим, я документирую это здесь, я получаю эту ошибку, потому что я ошибочно установил ng-модель так же, как и массив ng-repeat:

 <select ng-model="list_views">
     <option ng-selected="{{view == config.list_view}}"
         ng-repeat="view in list_views"
         value="{{view}}">
         {{view}}
     </option>
 </select>

Вместо:

<select ng-model="config.list_view">
     <option ng-selected="{{view == config.list_view}}"
         ng-repeat="view in list_views"
         value="{{view}}">
         {{view}}
     </option>
 </select>

Я проверил массив и не имел дубликатов, просто дважды проверьте свои переменные.

0

Дубликаты в ретрансляторе не допускаются. Используйте выражение "track by" для указания уникальных ключей. Повторитель: sdetail в mydt, Duplicate key: string:, Duplicate value:

Я столкнулся с этой ошибкой, потому что я написал неправильное имя базы данных в моей части php api......

Таким образом, эта ошибка может возникать и при извлечении данных из базы данных, имя которой написано вами некорректно.

0

Дубликаты в ретрансляторе не допускаются. Используйте выражение "track by" для указания уникальных ключей.

Repeater: {0}, Duplicate key: {1}, Duplicate value: {2}

Пример

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    <script src="angular.js"></script>

</head>
<body>
    <div ng-app="myApp" ng-controller="personController">
        <table>
            <tr> <th>First Name</th> <th>Last Name</th> </tr>
            <tr ng-repeat="person in people track by $index">
                <td>{{person.firstName}}</td>
                <td>{{person.lastName}}</td>
                <td><input type="button" value="Select" ng-click="showDetails($index)" /></td>
            </tr>

        </table> <hr />
        <table>
            <tr ng-repeat="person1 in items track by $index">
                <td>{{person1.firstName}}</td>
                <td>{{person1.lastName}}</td>
            </tr>
        </table>
        <span>   {{sayHello()}}</span>
    </div>
    <script> var myApp = angular.module("myApp", []);
        myApp.controller("personController", ['$scope', function ($scope)
        { 
            $scope.people = [{ firstName: "F1", lastName: "L1" },
                { firstName: "F2", lastName: "L2" }, 
                { firstName: "F3", lastName: "L3" }, 
                { firstName: "F4", lastName: "L4" }, 
                { firstName: "F5", lastName: "L5" }]
            $scope.items = [];
            $scope.selectedPerson = $scope.people[0];
            $scope.showDetails = function (ind) 
            { 
                $scope.selectedPerson = $scope.people[ind];
                $scope.items.push($scope.selectedPerson);
            }
            $scope.sayHello = function ()
            {
                return $scope.items.firstName;
            }
        }]) </script>
</body>
</html>
  • 2
    Пожалуйста, объявляйте всю принадлежность к любым ссылкам, которые вы публикуете
0

Мой ответ JSON был таким:

{"items": 
  &nbsp;[
    &nbsp;&nbsp;{
      "index": 1,
      "name": "Samantha",
      "rarity": "Scarborough",
      "email": "[email protected]"
    },
    &nbsp;&nbsp;{
      "index": 2,
      "name": "Amanda",
      "rarity": "Vick",
      "email": "[email protected]"
    }]
}

Итак, я использовал ng-repeat = "item in variables.items" для его отображения.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню