Kesalahan berulang-ulang sudut "Duplikat dalam pengulang tidak diizinkan."


472

Saya mendefinisikan filter khusus seperti:

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

Seperti yang Anda lihat ng-repeat di mana filter sedang digunakan bersarang di ng-repeat lain

Filter didefinisikan seperti ini:

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

Saya mendapatkan:

Kesalahan: Duplikat dalam pengulang tidak diizinkan. Pengulang: komentar di item.comments | range: 1: 2 ngRepeatAction @ https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/an

Jawaban:


954

Solusinya sebenarnya dijelaskan di sini: http://www.anujgakhar.com/2013/06/15/duplicates-in-a-repeater-are-not-allowed-in-angularjs/

AngularJS tidak mengizinkan duplikat dalam arahan ng-repeat. Ini berarti jika Anda mencoba melakukan hal berikut, Anda akan mendapatkan kesalahan.

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

Namun, mengubah kode di atas sedikit untuk menentukan indeks untuk menentukan keunikan seperti di bawah ini akan membuatnya berfungsi kembali.

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

Dokumen resmi ada di sini: https://docs.angularjs.org/error/ngRepeat/dupes


48
Saya ingin menyebutkan bahwa Anda dapat menerapkan properti pelacakan ubahsuaian untuk menentukan keunikan, bukan hanya $ indeks. Karena dalam skenario ini objek tidak memiliki properti lain ini berfungsi dengan baik. Alasan kesalahan ini terjadi adalah bahwa sudut menggunakan kamus untuk menyimpan id item sebagai kunci dengan nilai sebagai referensi DOM. Dari kode (baris 15402 di angular.js) sepertinya mereka melakukan caching elemen DOM yang sebelumnya ditemukan berdasarkan kunci mereka sebagai optimasi kinerja. Karena mereka membutuhkan kunci unik, mereka secara eksplisit melempar kesalahan ini ketika mereka menemukan kunci duplikat pada baris 15417
devshorts

16
<div ng-repeat="row in [1,1,1,2,2] |filter: 2 track by $index" >"filter pencarian" harus sebelum "track by $ index"
Zhe Hu

21
Astaga, desain jahat yang sia-sia di pihak Angular. Akan sangat, sangat mudah untuk melewatkan masalah ini selama pengembangan dan pengujian karena array Anda tidak pernah mengandung duplikat, hanya untuk membuat aplikasi Anda meledak dalam produksi ketika terkena dupes untuk pertama kalinya. Saya telah membangun aplikasi Angular sebelumnya tanpa mengetahui tentang batasan "no dupes"; Saya sekarang menemukan diri saya berpikir kembali dan bertanya-tanya apakah saya tanpa sadar menulis kode yang rusak.
Mark Amery

aplikasi kami telah meledak karena alasan ini dan saya bukan pengembang sudut, Apakah $indexada variabel di suatu tempat?
Chang Zhao

perhatikan ada peringatan jika Anda memperbarui elemen array Anda nanti tidak akan mengkompilasi ulang tag DOM, alih-alih menampilkan data basi. Anda dapat menggunakannya track by ($index + ':' + row)sehingga akan memperbarui individu <ng-repeat>kapan pun datanya diperbarui, serta ketika elemen baru ditambahkan, tanpa tersandung dupes
Hashbrown

45

Bagi mereka yang mengharapkan JSON dan masih mendapatkan kesalahan yang sama, pastikan Anda mengurai data Anda:

$scope.customers = JSON.parse(data)

4
ini tidak bekerja untuk saya, saya kira json, setelah menggunakan layanan $ http, tetapi SyntaxError: Token tak terduga o di Object.parse (asli)
aurelius

1
@Fergus senang ini bekerja untuk Anda; namun, pastikan untuk mencari perbedaan antara JSON.parse dan JSON.stringify kecuali Anda sudah tahu.
bermanfaatBee

2
Gila. Setelah berbulan-bulan bekerja dengan benar, Angular tiba-tiba memutuskan JSON yang dikembalikan dari $ http () bukan JSON lagi. Menguraikannya secara eksplisit memecahkan masalah ini bagi kami. Terima kasih atas saran gila.
Eric L.

12

Saya mengalami masalah dalam proyek saya di mana saya menggunakan ng-repeat track dengan $ index tetapi produk tidak mendapatkan refleksi ketika data berasal dari database. Kode saya adalah sebagai berikut:

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

Dalam kode di atas, produk adalah arahan terpisah untuk menampilkan produk. Tetapi saya mengetahui bahwa $ index menyebabkan masalah ketika kami meneruskan data dari ruang lingkup. Jadi kehilangan data dan DOM tidak bisa diperbarui.

Saya menemukan solusinya dengan menggunakan product.id sebagai kunci dalam ng-repeat seperti di bawah ini:

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

Tetapi kode di atas lagi gagal dan melempar kesalahan di bawah ini ketika lebih dari satu produk memiliki id yang sama:

angular.js: 11706 Kesalahan: [ngRepeat: dupes] Duplikat dalam pengulang tidak diperbolehkan. Gunakan ekspresi 'lacak per' untuk menentukan kunci unik. Pengulang

Jadi akhirnya saya menyelesaikan masalah dengan membuat kunci unik dinamis dari ng-repeat seperti di bawah ini:

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

Ini menyelesaikan masalah saya dan berharap ini akan membantu Anda di masa depan.


1
Tentunya track by $indexakan lebih baik daripada track by (product.id + $index)? Untuk satu hal, track by $indexlebih sederhana, dan untuk yang lain, Anda mungkin tidak benar-benar memiliki jaminan bahwa nilai-nilai (product.id + $index)akan unik. Misalnya, jika array Anda dimulai dengan produk dengan id5 dan setelah itu ada produk dengan id4, nilai (product.id + $index)keduanya akan menjadi 5 (5 + 0 untuk produk pertama, 4 +1 untuk yang kedua) dan Anda akan masih mendapatkan Duplikat dalam pengulang tidak diperbolehkan kesalahan.
Mark Amery

1
Saya setuju dengan $ index yang lebih sederhana tetapi solusi di atas berhasil bagi saya untuk menyelesaikan semua masalah yang saya hadapi dengan $ index. Dan dalam kasus saya product.id adalah alfanumerik sehingga (product.id + $ index) tidak dapat diduplikasi dalam hal apa pun. Jadi ide di balik solusi ini adalah bahwa jika $ index menyebabkan masalah apa pun dalam sebuah kasus maka kita dapat menggunakan logika apa pun dengan lintasan yang dibuat id secara unik.
Mahima Agrawal

5

Apa yang ingin Anda lakukan dengan filter "rentang"?

Berikut ini contoh yang berhasil dari apa yang saya pikir Anda coba lakukan: 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

Jika kebetulan kesalahan ini terjadi saat bekerja dengan SharePoint 2010: Ganti nama ekstensi file .json Anda dan pastikan untuk memperbarui jalur restService Anda. Tidak diperlukan tambahan "track by $ index".

Untungnya saya meneruskan tautan ini ke alasan ini:

.json menjadi tipe file penting di SP2010. SP2010 mencakup titik akhir layanan web tertentu. Lokasi file-file ini adalah folder 14hive \ isapi. Ekstensi file-file ini adalah .json. Itulah alasannya memberikan kesalahan seperti itu.

"Hanya peduli bahwa isi file json adalah json - bukan ekstensi file"

Setelah ekstensi file diubah, harus siap.


0

Kalau-kalau ini terjadi pada orang lain, saya mendokumentasikan ini di sini, saya mendapatkan kesalahan ini karena saya keliru mengatur model-ng sama dengan array 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>

Dari pada:

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

Saya memeriksa array dan tidak memiliki duplikat, cukup periksa variabel Anda.


0

Duplikat dalam pengulang tidak diizinkan. Gunakan ekspresi 'lacak per' untuk menentukan kunci unik.

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

Contoh

<!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
Silakan nyatakan semua afiliasi ke tautan apa pun yang Anda poskan
Draken


-1

JSONRespons saya seperti ini:

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

Jadi, saya biasa ng-repeat = "item in variables.items" menampilkannya.


-1

Duplikat dalam pengulang tidak diizinkan. Gunakan ekspresi 'lacak per' untuk menentukan kunci unik. Pengulang: sdetail di mydt, Kunci duplikat: string:, Nilai duplikat:

Saya menghadapi kesalahan ini karena saya telah menulis nama database yang salah di bagian php api saya ......

Jadi kesalahan ini juga dapat terjadi ketika Anda mengambil data dari basis data, yang namanya salah ditulis oleh Anda.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.