각도 ng-repeat 오류“중계기의 복제는 허용되지 않습니다.”


472

다음과 같이 사용자 정의 필터를 정의하고 있습니다.

<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의 주석 | range : 1 : 2 ngRepeatAction @ https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/an

답변:


955

해결책은 실제로 여기에 설명되어 있습니다. 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뿐만 아니라 모든 사용자 정의 추적 속성을 적용하여 고유성을 정의 할 수 있다고 언급하고 싶습니다. 이 시나리오에서 객체에는 다른 속성이 없으므로 제대로 작동합니다. 이 오류가 발생하는 이유는 각도가 사전을 사용하여 값을 DOM 참조로 사용하여 항목의 ID를 키로 저장하기 때문입니다. 코드 (angular.js의 15402 행)에서 성능 최적화로서 키를 기반으로 이전에 찾은 DOM 요소를 캐싱하는 것처럼 보입니다. 고유 키가 필요하기 때문에 15417 행에서 중복 키를 발견하면 명시 적으로이 오류가 발생합니다.
devshorts

16
<div ng-repeat="row in [1,1,1,2,2] |filter: 2 track by $index" >"검색 필터"는 "track by $ index"앞에 있어야합니다.
Zhe Hu

21
Angular는 무의미하게 불쾌한 디자인을하는 Yikes. 배열에 복제본이 포함되어 있지 않기 때문에 개발 및 테스트 중에이 문제를 놓치기가 매우 쉽고 매우 쉽습니다. "무중단 없음"제한에 대해 몰라도 전에 Angular 앱을 만들었습니다. 나는 이제 내가 생각하고 실수로 깨진 코드를 무의식적으로 작성했는지 궁금해하고있다.
Mark Amery

이 이유로 인해 앱이 폭발했으며 각도 개발자가 아닙니다. $index변수가 어딘가에 있습니까?
Chang Zhao

나중에 배열 요소를 업데이트하면 DOM 태그를 다시 컴파일하지 않고 오래된 데이터가 표시되는 것에주의해야합니다. 당신은 데이터를 업데이트 할 때마다 그리고 새로운 요소가 추가 될 때마다 track by ($index + ':' + row)개별 항목을 업데이트 할 수 있습니다.<ng-repeat>
Hashbrown

45

JSON을 기대하면서도 여전히 같은 오류가 발생하는 경우 데이터를 구문 분석해야합니다.

$scope.customers = JSON.parse(data)

4
이것은 나를 위해 작동하지 않습니다, 나는 $ http 서비스를 사용한 후 json을 기대하지만 SyntaxError : Object.parse에서 예기치 않은 토큰 o (native)
aurelius

1
@ Fergus는 이것이 당신을 위해 일하는 것을 기쁘게 생각합니다. 그러나 아직 모를 경우 JSON.parse와 JSON.stringify의 차이점을 찾아보십시오.
유용한 Bee

2
미친. 몇 달 동안 올바르게 작업 한 후 Angular는 $ http ()에서 반환 된 JSON이 더 이상 JSON이 아니라고 갑자기 결정했습니다. 명시 적으로 파싱하면이 문제가 해결되었습니다. 미친 제안에 감사드립니다.
Eric L.

12

내 프로젝트에서 $ index로 ng-repeat 트랙을 사용하는 데 문제가 있었지만 데이터베이스에서 데이터를 가져올 때 제품에 반영되지 않았습니다. 내 코드는 다음과 같습니다.

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

위의 코드에서 product는 제품을 표시하는 별도의 지시문이지만 범위에서 데이터를 전달할 때 $ index로 인해 문제가 발생한다는 것을 알게되었습니다. 따라서 데이터 손실 및 DOM을 업데이트 할 수 없습니다.

다음과 같이 product.id를 ng-repeat의 키로 사용하여 솔루션을 찾았습니다.

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

그러나 둘 이상의 제품에 동일한 ID가 있으면 위의 코드가 다시 실패하고 아래 오류가 발생합니다.

angular.js : 11706 오류 : [ngRepeat : dupes] 리피터의 중복은 허용되지 않습니다. 고유 한 키를 지정하려면 '추적 기준'표현식을 사용하십시오. 연발총

그래서 마지막으로 아래와 같이 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)이 고유 하다는 것을 보장하지는 않습니다 . 예를 들어, 어레이가 id5 의 제품으로 시작한 후 id4 의 제품이 있으면 값은 (product.id + $index)5 (첫 번째 제품의 경우 5 + 0, 두 번째 제품의 경우 4 + 1)가되고 여전히 repeater중복은 오류가 허용되지 않습니다 .
Mark Amery 22시 42 분

1
나는 $ 인덱스가 더 간단하다는 것에 동의하지만 위의 솔루션은 내가 $ 인덱스에 직면 한 모든 문제를 해결하기 위해 작동합니다. 그리고 내 경우 product.id는 영숫자이므로 (product.id + $ index)는 어떤 경우에도 복제 할 수 없습니다. 따라서이 솔루션의 기본 아이디어는 $ index가 어떤 경우에 문제를 일으키는 경우 ID가 고유하게 생성되는 모든 로직을 추적 할 수 있다는 것입니다.
Mahima Agrawal

5

"범위"필터는 무엇을 하시겠습니까?

여기에 내가 무엇을 작업 예제의 생각 당신이해야 할 노력하고는 : 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'
            ]
        }
    ];
}

1

우연히이 오류가 SharePoint 2010 작업시 발생하는 경우 : .json 파일 확장자의 이름을 바꾸고 restService 경로를 업데이트하십시오. 추가로 "$ index by track"이 필요하지 않았습니다.

운 좋게 나는 이 근거에 대한 이 링크 를 전달 받았다 .

.json은 SP2010에서 중요한 파일 형식이되었습니다. SP2010에는 특정 웹 서비스 끝 점이 포함되어 있습니다. 이 파일들의 위치는 14hive \ isapi 폴더입니다. 이 파일의 확장자는 .json입니다. 그것이 그러한 오류를 일으키는 이유입니다.

"json 파일의 내용이 json임을주의하십시오-파일 확장자가 아닙니다"

파일 확장자가 변경되면 모두 설정해야합니다.


0

이 문제가 다른 사람에게 발생하는 경우 여기에 문서화하고 있는데 실수로 ng-model을 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

리피터의 복제는 허용되지 않습니다. 고유 한 키를 지정하려면 '추적 기준'표현식을 사용하십시오.

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
게시 한 모든 링크에 모든 제휴 관계를 선언하십시오
Draken


-1

JSON응답은 다음과 같습니다.

{"items": 
  &nbsp;[
    &nbsp;&nbsp;{
      "index": 1,
      "name": "Samantha",
      "rarity": "Scarborough",
      "email": "maureen@sykes.mk"
    },
    &nbsp;&nbsp;{
      "index": 2,
      "name": "Amanda",
      "rarity": "Vick",
      "email": "jessica@livingston.mv"
    }]
}

그래서 나는 ng-repeat = "item in variables.items" 그것을 표시하는 데 사용 했습니다.


-1

리피터의 복제는 허용되지 않습니다. 고유 한 키를 지정하려면 '추적 기준'표현식을 사용하십시오. 리피터 : mydt의 sdetail, 중복 키 : 문자열 :, 중복 값 :

내 PHP API 부분에 잘못된 데이터베이스 이름 을 작성했기 때문에이 오류에 직면했습니다 ...

따라서이 오류는 이름이 잘못 작성된 데이터베이스 기반에서 데이터를 가져 오는 경우에도 발생할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.