Angular ng-repeat Error「リピーターの重複は許可されていません。」


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だけでなく、カスタムトラッキングプロパティを適用して一意性を定義できることを述べておきます。このシナリオでは、オブジェクトに他のプロパティがないため、これは正常に機能します。このエラーが発生する理由は、angularがディクショナリを使用して、アイテムのIDをキーとして、値をDOM参照として格納しているためです。コード(angular.jsの行15402)から、パフォーマンスの最適化として、キーに基づいて以前に見つかったDOM要素をキャッシュしているように見えます。彼らは一意のキーを必要とするため、行15417で重複するキーを見つけたときに明示的にこのエラーをスローします
devshorts

16
<div ng-repeat="row in [1,1,1,2,2] |filter: 2 track by $index" >「検索フィルター」は「$ indexで追跡」の前にある必要があります
Zhe Hu

21
いや、Angularのデザインが無意味に厄介だ。配列に重複が含まれることはないので、開発やテスト中にこの問題を見逃すのは非常に簡単です。アプリが初めてdupeに公開されたときに本番環境で爆発するだけです。私は以前に、「複製禁止」の制限について知らずに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(native)での予期しないトークンo
aurelius

1
@Fergusさん、これでうまくいきました。ただし、すでにわかっている場合を除き、JSON.parseとJSON.stringifyの違いを確認してください。
役に立つBee

2
クレイジー。Angularは何ヶ月も正しく動作した後、$ http()から返されたJSONがJSONではなくなったと突然判断しました。明示的に解析すると、この問題は解決されました。クレイジーな提案をありがとう。
エリックL.

12

$ indexによるng-repeatトラックを使用していたプロジェクトで問題が発生しましたが、データベースからデータが取得されると製品が反映されませんでした。私のコードは以下の通りです:

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

上記のコードでは、productは製品を表示する別のディレクティブですが、スコープからデータを渡すときに$ indexが問題を引き起こすことを知りました。したがって、データ損失とDOMは更新できません。

以下のようにng-repeatのキーとしてproduct.idを使用して解決策を見つけました:

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

しかし、上記のコードは再び失敗し、複数の製品に同じIDが付属している場合、以下のエラーがスローされます。

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)?1つtrack by $indexは単純で、もう1つは、実際にはの値(product.id + $index)が一意であるという保証はありません。たとえば、配列がid5の製品で始まり、その後idに4の製品がある場合、それらの値(product.id + $index)は両方とも5(最初の製品は5 + 0、2番目の製品は4 + 1)であり、それでもリピーターで重複を取得することはできませんエラーです。
Mark Amery、2016年

1
$インデックスの方が単純であることに同意しますが、上記の解決策は私が$インデックスで直面していたすべての問題を解決するために機能します。また、私の場合、product.idは英数字であるため、(product.id + $ index)を重複させることはできません。したがって、このソリューションの背後にある考えは、$ indexがケースで問題を引き起こしている場合、一意に作成されたIDで追跡されるロジックを使用できるということです。
Mahima Agrawal 2016年

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による追跡」は必要ありませんでした。

幸いにも私はこのリンクをこの理論的根拠に転送しました:

.jsonは、SP2010で重要なファイルタイプになります。SP2010には、特定のWebサービスエンドポイントが含まれています。これらのファイルの場所は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

リピーターでの重複は許可されていません。'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
投稿するリンクへの所属はすべて宣言してください
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

リピーターでの重複は許可されていません。'track by'式を使用して、一意のキーを指定します。リピーター:mydtの詳細、重複キー:文字列:、重複値:

私のphp apiパーツに間違ったデータベース名を書き込んだため、このエラーに直面しました......

そのため、このエラーは、データベースベースからデータをフェッチしているときにも発生する可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.