JSON.stringifyの結果に追加された$$ hashKeyは何ですか


288

私は彼らのドキュメントのMozilla JSON文字列化ページだけでなく、SOやGoogleでもここで調べましたが、説明はありませんでした。私はJSOn文字列化を何度も使用しましたが、この結果に遭遇したことはありません

JSONオブジェクトの配列があります

[
    {
        "param_2": "Description 1",
        "param_0": "Name 1",
        "param_1": "VERSION 1"
    },
    {
        "param_2": "Description 2",
        "param_0": "Name 2",
        "param_1": "VERSION 2"
    },
    {
        "param_2": "Description 3",
        "param_0": "Name 3",
        "param_1": "VERSION 3"
    }
]

私に添付$scopeし、するために、POST1つのparamaterが、私はJSON.stringify()メソッドを使用して、私は次のことを得るようにそれら:

   [
        {
            "param_2": "Description 1",
            "param_0": "Name 1",
            "param_1": "VERSION 1",
            "$$hashKey": "005"
        },
        {
            "param_2": "Description 2",
            "param_0": "Name 2",
            "param_1": "VERSION 2",
            "$$hashKey": "006"
        },
        {
            "param_2": "Description 3",
            "param_0": "Name 3",
            "param_1": "VERSION 3",
            "$$hashKey": "007"
        }
    ]

stringifyメソッドから次のようなものを期待していたので、$$ hashkeyが正確に何であるかを知りたいだけです。

[
    {
        "1":{
            "param_2": "Description 1",
            "param_0": "Name 1",
            "param_1": "VERSION 1"
        },
         "2":{
            "param_2": "Description 2",
            "param_0": "Name 2",
            "param_1": "VERSION 2"
        },
         "3":{
            "param_2": "Description 3",
            "param_0": "Name 3",
            "param_1": "VERSION 3"
        }
    }
]

それが要因かどうかはわかりませんが、使用しています Angularjs 1.1.5, JQuery 1.8.2 and Spring 3.0.4 and Spring security 3.0.7 on the Server side

問題の原因にはなりませんが、原因と理由を知りたいのですが $$hashkey


8
angularjsによって追加されました
Arun P Johny


69
代わりJSON.stringify使用angular.toJson()
アルンPジョニー

いずれかの答えとしてあなたの説明を追加したい場合おかげでみんな、私は受け入れるように幸せになる
ジョニー・

1
この答えは素晴らしい説明です。.stackoverflow.com/questions/12336897
チャーリーマーティン

回答:


530

Angularはこれを追加して変更を追跡し、いつDOMを更新する必要があるかを認識します。

angular.toJson(obj)代わりにを使用するとJSON.stringify(obj)、Angularはこれらの内部使用値を削除します。

また、track by {uniqueProperty}サフィックスを使用するように繰り返し式を変更する場合、Angularはまったく追加する必要がありません$$hashKey。例えば

<ul>
    <li ng-repeat="link in navLinks track by link.href">
        <a ng-href="link.href">{{link.title}}</a>
    </li>
</ul>

常に「リンク」が必要であることを覚えておいてください。表現の一部-私はいつもそれを忘れがちです。ただ、track by href確実に動作しません。


«track by»と«$$ hashKey»に関するパフォーマンステストはありますか?(UPD。
わかりました。ググって

@artuska IDで追跡するには...何のハッシュがちょうど再利用、既存のIDあなたを計算していないか、カウンタをインクリメントする必要があるように非常に簡単です
クリストフRoussy

3
適用するフィルターがある場合、正しい順序は次のとおりitem in somelist | filter:somefilter track by item.keyです。、行の最後にフィルターを記述しないでください。
Lewen

1
注意!私は、コピーして要素を配列に挿入し、それをng-repeatでレンダリングするcloneメソッドで配列を使用していました。JSON.parse(JSON.stringify(obj))を使用して要素を複製すると、角度の「重複キー」エラーが発生しました。JSON.parse(angular.toJson(obj));の使用 固定されたもの。ありがとう!
SAL

1
データを表示しているだけの場合に、ダブルコロン::を使用してワンタイムバインディング機能を使用し、更新されないようにすることもできます。<a ng-href="link.href"> {{:: link.title}} </a>
フィル

70

私のユースケース(結果のオブジェクトをX2JSにフィードする)では、推奨されるアプローチ

data = angular.toJson(source);

$$hashKeyプロパティの削除に役立ちますが、結果はX2JSで処理できなくなります。

data = angular.copy(source);

$$hashKeyプロパティも削除しましたが、結果はX2JSのパラメーターとして引き続き使用できました。


37

通常、ng-repeatディレクティブが付属しています。dom操作を行うには、AngularJSフラグオブジェクトに特別なIDを付けます。

これはAngularと共通です。たとえば、ngResourceでオブジェクトを取得すると、オブジェクトにすべてのリソースAPIが埋め込まれ、$ saveなどのメソッドが表示されます。Cookieを使用すると、AngularJSによって__ngDebugプロパティが追加されます。


これらのプロパティを削除するにはどうすればよいですか?angularはそれを行う方法を提供しますか?
ニレシュ2014年

1
そのプロパティを削除しようとすると、角度モデルが壊れます。変数をコピーすることをお勧めします。ハッシュキーを除外する方法については、@ David-Boikeの回答をご覧ください
Josue Alexander Ibarra '19

23

データにIDを追加したくない場合は、配列内のインデックスで追跡できます。これにより、項目の値ではなく、配列内の位置がキーになります。

このような:

var myArray = [1,1,1,1,1];

<li ng-repeat="item in myArray track by $index">

これには、アイテムの順序が決して変わらないという前提が必要です。:)
ニートコーディング

8

Angular 1.3以上を使用している場合は、ng-repeatで「track by」を使用することをお勧めします。Angularは、「track by」を使用する場合、配列内のオブジェクトに「$$ hashKey」プロパティを追加しません。また、パフォーマンス上の利点も得られます。配列内の何かが変更された場合、angularはng-repeatのDOM構造全体を再作成せず、変更された配列内の値のDOMの部分を再作成します。


4

更新:Angular v1.5から、track by $indexはリンクを使用する代わりに標準の構文になりましたng-repeatバイ重複エラーが発生しました。

私はネストされてこれに遭遇しng-repeat、以下が機能しました。

<tbody>
    <tr ng-repeat="row in data track by $index">
    <td ng-repeat="field in headers track by $index">{{row[field.caption] }}</td>
</tr>

明確にするために-track by式で使用される属性は、繰り返されるコレクション全体で一意である必要があります。$ indexは1つのオプションです。ほとんどの場合、
それで

これには、アイテムの順序が決して変わらないという前提が必要です。:)
ニートコーディング

3

オブジェクトから$$ hashKeyを簡単に削除する方法は次のとおりです。

$scope.myNewObject = JSON.parse(angular.toJson($scope.myObject))

$scope.myObject -操作を実行するオブジェクトを参照します。つまり、$$ hashKeyを削除します

$scope.myNewObject -必要に応じて使用できるように、変更された元のオブジェクトを新しいオブジェクトに割り当てます


これは不必要に複雑だと思います。その単一のフィールド、または$で始まるすべてのフィールドを削除できます。しかしおそらく必要はありません-他の答えを見てください。
sevcsik 2017年

1

https://www.timcosta.io/angular-js-object-comparisons/

Angularは、人々が初めてそれを目にしたとき、かなり不思議です。JSの変数を更新すると、自動DOM更新が行われ、誰かがDOMの値を更新すると、同じ変数がJSファイルで更新されます。これと同じ機能が、ページ要素全体およびコントローラー全体で機能します。

これらすべての鍵となるのは、ng-repeatで使用されるオブジェクトと配列への$$ hashKey Angularアタッチです。

この$$ hashKeyは、余分なデータを削除しないAPIに完全なオブジェクトを送信している人々に多くの混乱を引き起こします。APIはすべてのリクエストに対して400を返しますが、その$$ hashKeyはオブジェクトから離れません。

Angularは$$ hashKeyを使用して、ng-repeatでループされている配列のどのアイテムにDOMのどの要素が属しているかを追跡します。$$ hashKeyがなければ、Angularは、JavaScriptまたはDOMで発生した変更を対応する相手に適用することができません。これは、Angularの主な用途の1つです。

この配列を考えてみましょう:

users = [  
    {
         first_name: "Tim"
         last_name: "Costa"
         email: "tjsail33@gmail.com"
    }
]

ng-repeat = "user in users"を使用してそれをリストにレンダリングした場合、その中の各オブジェクトは、Angularからの追跡目的で$$ hashKeyを受け取ります。この$$ hashKeyを回避する2つの方法を次に示します。

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