Lỗi lặp lại góc Ang Lỗi Sao chép trong bộ lặp không được phép.


472

Tôi đang xác định một bộ lọc tùy chỉnh như vậy:

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

Như bạn có thể thấy ng-repeat trong đó bộ lọc đang được sử dụng được lồng trong một ng-repeat khác

Bộ lọc được định nghĩa như thế này:

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

Tôi nhận được:

Lỗi: Không được phép sao chép trong bộ lặp. Repeater: bình luận trong item.comments | phạm vi: 1: 2 ngRepeatAction @ https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/an

Câu trả lời:


955

Giải pháp thực sự được mô tả ở đây: http://www.anujgakhar.com/2013/06/15/d repeatates-in-a-repeater-are-not -allowed-in-angularjs /

AngularJS không cho phép trùng lặp trong một lệnh lặp lại ng. Điều này có nghĩa là nếu bạn đang cố gắng làm như sau, bạn sẽ gặp lỗi.

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

Tuy nhiên, thay đổi một chút mã ở trên để xác định một chỉ mục để xác định tính duy nhất như dưới đây sẽ khiến nó hoạt động trở lại.

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

Tài liệu chính thức có tại đây: https://docs.angularjs.org/error/ngRepeat/dupes


48
Tôi muốn đề cập rằng bạn có thể áp dụng bất kỳ thuộc tính theo dõi tùy chỉnh nào để xác định tính duy nhất, không chỉ là chỉ mục $. Vì trong kịch bản này, các đối tượng không có bất kỳ thuộc tính nào khác, điều này hoạt động tốt. Lý do lỗi này xảy ra là do angular đang sử dụng từ điển để lưu trữ id của một mục làm khóa với giá trị là tham chiếu DOM. Từ mã (dòng 15402 trong angular.js), có vẻ như chúng đang lưu trữ các phần tử DOM được tìm thấy trước đó dựa trên khóa của chúng dưới dạng tối ưu hóa hiệu suất. Vì họ cần các khóa duy nhất nên họ đã ném lỗi này một cách rõ ràng khi họ tìm thấy các khóa trùng lặp trên dòng 15417
devshorts

16
<div ng-repeat="row in [1,1,1,2,2] |filter: 2 track by $index" >"bộ lọc tìm kiếm" cần có trước "theo dõi bởi chỉ số $"
Zhe Hu

21
Rất tiếc, thiết kế vô cùng khó chịu về phía Angular. Sẽ rất, rất dễ bỏ lỡ vấn đề này trong quá trình phát triển và thử nghiệm vì mảng của bạn không bao giờ chứa các bản sao, chỉ để ứng dụng của bạn phát nổ trong sản xuất khi lần đầu tiên tiếp xúc với bản sao. Tôi đã xây dựng các ứng dụng Angular trước đây mà không biết về hạn chế "không lừa đảo"; Bây giờ tôi thấy mình suy nghĩ lại và tự hỏi liệu tôi có vô tình tác giả mã bị hỏng không.
Mark Amery

Ứng dụng của chúng tôi đã phát nổ vì lý do này và tôi không phải là nhà phát triển góc cạnh, $indexBiến có tồn tại ở đâu đó không?
Chang Zhao

lưu ý rằng có một cảnh báo nếu bạn cập nhật các phần tử mảng của mình sau đó nó sẽ không biên dịch lại các thẻ DOM, thay vào đó hiển thị dữ liệu cũ. Bạn có thể sử dụng track by ($index + ':' + row)để nó sẽ cập nhật từng cá nhân <ng-repeat>bất cứ khi nào dữ liệu của nó được cập nhật, cũng như khi một yếu tố mới được thêm vào, mà không bị vấp vào các bản sao
Hashbrown

45

Đối với những người mong đợi JSON và vẫn gặp lỗi tương tự, hãy đảm bảo rằng bạn phân tích dữ liệu của mình:

$scope.customers = JSON.parse(data)

4
điều này không hiệu quả với tôi, tôi mong json, sau khi sử dụng dịch vụ $ http, nhưng SyntaxError: Mã thông báo bất ngờ o tại Object.parse (bản địa)
aurelius 18/03/2015

1
@Fergus rất vui vì điều này hiệu quả với bạn; tuy nhiên, hãy đảm bảo tìm kiếm sự khác biệt giữa JSON.parse và JSON.opesify trừ khi bạn đã biết.
hữu íchBee

2
Khùng. Sau nhiều tháng hoạt động chính xác, Angular đột ngột quyết định JSON được trả về từ $ http () không còn là JSON. Rõ ràng phân tích cú pháp nó đã giải quyết vấn đề này cho chúng tôi. Cảm ơn lời đề nghị điên rồ.
Eric L.

12

Tôi đã gặp sự cố trong dự án của mình khi tôi đang sử dụng theo dõi lặp lại bởi $ index nhưng các sản phẩm không được phản ánh khi dữ liệu đến từ cơ sở dữ liệu. Mã của tôi là như sau:

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

Trong đoạn mã trên, sản phẩm là một chỉ thị riêng để hiển thị sản phẩm. Nhưng tôi đã biết rằng $ index gây ra vấn đề khi chúng tôi chuyển dữ liệu ra khỏi phạm vi. Vì vậy, mất dữ liệu và DOM không thể được cập nhật.

Tôi đã tìm thấy giải pháp bằng cách sử dụng sản phẩm .id làm chìa khóa trong ng-repeat như dưới đây:

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

Nhưng mã trên lại thất bại và đưa ra lỗi bên dưới khi có nhiều hơn một sản phẩm có cùng id:

angular.js: 11706 Lỗi: [ngRepeat: dupes] Không được phép sao chép trong bộ lặp. Sử dụng biểu thức 'theo dõi' để chỉ định các khóa duy nhất. Lặp lại

Vì vậy, cuối cùng tôi đã giải quyết vấn đề bằng cách tạo khóa duy nhất động của ng-repeat như bên dưới:

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

Điều này đã giải quyết vấn đề của tôi và hy vọng điều này sẽ giúp bạn trong tương lai.


1
Chắc chắn track by $indexsẽ tốt hơn track by (product.id + $index)? Đối với một điều, track by $indexđơn giản hơn, và đối với một điều khác, có lẽ bạn thực sự không có bất kỳ đảm bảo rằng các giá trị của (product.id + $index)sẽ là duy nhất. Chẳng hạn, nếu mảng của bạn bắt đầu bằng một sản phẩm có id5 và sau đó có một sản phẩm có id4, giá trị của (product.id + $index)chúng sẽ là 5 (5 + 0 cho sản phẩm đầu tiên, 4 + 1 cho sản phẩm thứ hai) và bạn sẽ vẫn nhận được các bản sao trong bộ lặp không bị lỗi.
Đánh dấu Amery

1
Tôi đồng ý với chỉ số $ đơn giản hơn nhưng giải pháp trên được thực hiện để tôi giải quyết tất cả các vấn đề tôi gặp phải với chỉ số $. Và trong trường hợp của tôi, Product.id là chữ và số, vì vậy (Product.id + $ index) không thể bị trùng lặp trong mọi trường hợp. Vì vậy, ý tưởng đằng sau giải pháp này là nếu $ index gây ra bất kỳ vấn đề nào trong một trường hợp thì chúng ta có thể sử dụng bất kỳ logic nào với theo dõi được tạo id duy nhất.
Mahima Agrawal

5

Bạn dự định bộ lọc "phạm vi" của bạn sẽ làm gì?

Đây là một ví dụ hoạt động về những gì tôi nghĩ bạn đang cố gắng thực hiện: 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

Nếu tình cờ lỗi này xảy ra khi làm việc với SharePoint 2010: Đổi tên phần mở rộng tệp .json của bạn và đảm bảo cập nhật đường dẫn restService của bạn. Không yêu cầu "theo dõi bởi chỉ số $".

May mắn thay, tôi đã được chuyển tiếp liên kết này đến lý do này:

.json trở thành một loại tệp quan trọng trong SP2010. SP2010 bao gồm các điểm cuối dịch vụ web xác nhận. Vị trí của các tệp này là thư mục 14hive \ isapi. Phần mở rộng của các tệp này là .json. Đó là lý do nó đưa ra một lỗi như vậy.

"chỉ quan tâm rằng nội dung của tệp json là json - không phải phần mở rộng tệp của nó"

Khi các phần mở rộng tập tin được thay đổi, nên được thiết lập tất cả.


0

Chỉ trong trường hợp điều này xảy ra với người khác, tôi đang ghi lại điều này ở đây, tôi đã gặp lỗi này vì tôi đã đặt nhầm mô hình ng giống như mả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>

Thay vì:

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

Tôi đã kiểm tra mảng và không có bất kỳ sự trùng lặp nào, chỉ cần kiểm tra lại các biến của bạn.


0

Bản sao trong một bộ lặp không được phép. Sử dụng biểu thức 'theo dõi' để chỉ định các khóa duy nhất.

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

Thí dụ

<!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
Vui lòng khai báo tất cả các liên kết đến bất kỳ liên kết nào bạn đăng
Draken

0

Nếu bạn gọi ng-repeat trong thẻ <ul>, bạn có thể cho phép trùng lặp. Xem liên kết này để tham khảo. Xem Todo2.html


-1

Câu JSONtrả lời của tôi là như thế này:

{"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"
    }]
}

Vì vậy, tôi đã từng ng-repeat = "item in variables.items" hiển thị nó.


-1

Bản sao trong một bộ lặp không được phép. Sử dụng biểu thức 'theo dõi' để chỉ định các khóa duy nhất. Repeater: sdetail trong mydt, Khóa trùng lặp: chuỗi :, Giá trị trùng lặp:

Tôi gặp phải lỗi này vì tôi đã viết sai tên cơ sở dữ liệu trong phần php api của mình ......

Vì vậy, lỗi này cũng có thể xảy ra khi bạn đang tìm nạp dữ liệu từ cơ sở dữ liệu, tên của bạn được viết không chính xác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.