Was ist der $$ hashKey, der meinem JSON.stringify-Ergebnis hinzugefügt wurde?

288

Ich habe versucht, auf der Mozilla JSON-Stringify- Seite ihrer Dokumente sowie hier auf SO und Google nachzuschauen, aber keine Erklärung gefunden. Ich habe JSOn stringify viele Male verwendet, bin aber nie auf dieses Ergebnis gestoßen

Ich habe ein Array von JSON-Objekten

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

an meine $scopeund um POSTsie als eine Paramater ich die JSON.stringify () -Methode verwendet , und ich erhalte die folgende:

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

Ich bin nur neugierig, was genau der $$ Hashkey ist, da ich von der stringify-Methode etwas Ähnliches wie das Folgende erwartet habe:

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

Ich bin nicht sicher, ob es ein Faktor ist, aber ich benutze Angularjs 1.1.5, JQuery 1.8.2 and Spring 3.0.4 and Spring security 3.0.7 on the Server side

Es verursacht mir keine Probleme, aber ich würde gerne die Ursache und den Grund dafür kennen $$hashkey

Jonnie
quelle
8
es wird von anglejs hinzugefügt
Arun P Johny
69
anstelle von JSON.stringify verwenden Sie angle.toJson ()
Arun P Johny
Vielen Dank, Leute, wenn jemand Ihre Erklärung als Antwort hinzufügen möchte, würde ich gerne akzeptieren
jonnie
1
Diese Antwort ist eine gute Erklärung .. stackoverflow.com/questions/12336897/…
Charlie Martin

Antworten:

530

Angular fügt dies hinzu, um Ihre Änderungen zu verfolgen, damit es weiß, wann das DOM aktualisiert werden muss.

Wenn Sie angular.toJson(obj)anstelle von verwendenJSON.stringify(obj) , werden diese Werte für den internen Angular für Sie entfernt.

Wenn Sie Ihren Wiederholungsausdruck ändern, um das track by {uniqueProperty}Suffix zu verwenden, muss Angular überhaupt nichts hinzufügen $$hashKey. Beispielsweise

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

Denken Sie immer daran, dass Sie den "Link" benötigen. Teil des Ausdrucks - das vergesse ich immer. track by hrefWird einfach sicher nicht funktionieren.

David Boike
quelle
Gibt es Leistungstests zu «track by» vs «$$ hashKey»? (UPD. Ok, ich habe es gegoogelt und «Track by» ist vorzuziehen)
Artuska
@artuska Tracking nach ID ist sehr einfach, da keine Hashes berechnet werden müssen. Sie verwenden nur vorhandene IDs wieder oder erhöhen einen Zähler ...
Christophe Roussy
3
und wenn Sie einen Filter anwenden müssen, ist hier die richtige Reihenfolge: item in somelist | filter:somefilter track by item.keySchreiben Sie den Filter nicht am Ende der Zeile!
Lewen
1
Hinweis! Ich habe ein Array mit einer Klonmethode verwendet, die Elemente kopiert und dann in ein Array eingefügt hat, das dann durch eine ng-Wiederholung gerendert wurde. Bei der Verwendung von JSON.parse (JSON.stringify (obj)) zum Klonen meines Elements wurden eckige Fehler beim Kopieren von Schlüsseln angezeigt. Verwenden von JSON.parse (angle.toJson (obj)); feste Dinge. Vielen Dank!
SAL
1
Sie können die Funktion "Einmalige Bindung" auch mit Doppelpunkt :: verwenden, um zu verhindern, dass sie aktualisiert wird, wenn Sie nur Daten anzeigen. <a ng-href="link.href"> {{:: link.title}} </a>
Phil
70

In meinem Anwendungsfall (Zuführen des resultierenden Objekts zu X2JS) der empfohlene Ansatz

data = angular.toJson(source);

helfen, die $$hashKeyEigenschaften zu entfernen , aber das Ergebnis konnte dann nicht mehr von X2JS verarbeitet werden .

data = angular.copy(source);

Die $$hashKeyEigenschaften wurden ebenfalls entfernt, aber das Ergebnis blieb als Parameter für X2JS verwendbar.

rob2universe
quelle
37

Es kommt normalerweise mit der ng-repeat-Direktive. Dom-Manipulation AngularJS kennzeichnet Objekte mit einer speziellen ID.

Dies ist bei Angular üblich. Wenn Sie beispielsweise ein Objekt mit ngResource abrufen, wird in Ihr Objekt die gesamte Ressourcen-API eingebettet, und es werden Methoden wie $ save usw. angezeigt. Auch bei Cookies fügt AngularJS eine Eigenschaft __ngDebug hinzu.

Thomas Pons
quelle
Wie soll ich diese Eigenschaften entfernen? Bietet Angular eine Möglichkeit, dies zu tun?
Nilesh
1
Winkelmodelle werden beschädigt, wenn Sie versuchen, diese Eigenschaft zu entfernen. Ich empfehle, die Variable zu kopieren. Siehe @ David-Boikes Antwort zum Herausfiltern des Hashkeys
Josue Alexander Ibarra
23

Wenn Sie Ihren Daten keine IDs hinzufügen möchten, können Sie diese anhand des Index im Array verfolgen. Dadurch werden die Elemente anhand ihrer Position im Array anstelle ihres Werts verschlüsselt.

So was:

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

<li ng-repeat="item in myArray track by $index">
Michael Falck Wedelgård
quelle
Dies setzt voraus, dass sich die Reihenfolge Ihrer Artikel niemals ändert. :)
ordentliches Codieren
8

Wenn Sie Angular 1.3 oder höher verwenden, empfehle ich, dass Sie in Ihrer ng-Wiederholung "track by" verwenden. Angular fügt den Objekten in Ihrem Array keine "$$ hashKey" -Eigenschaft hinzu, wenn Sie "track by" verwenden. Sie erhalten auch Leistungsvorteile: Wenn sich etwas in Ihrem Array ändert, erstellt Angular nicht die gesamte DOM-Struktur für Ihre ng-Wiederholung neu, sondern erstellt stattdessen den Teil des DOM für die Werte in Ihrem Array, die sich geändert haben.

Ajay Ullal
quelle
4

Update: Ab Angular v1.5 ist Track By $indexjetzt die Standardsyntax, anstatt Link zu verwenden, da ich einen ng-repeatDupes-Fehler hatte.

Ich bin darauf für ein verschachteltes gestoßen ng-repeatund das unten hat funktioniert.

<tbody>
    <tr ng-repeat="row in data track by $index">
    <td ng-repeat="field in headers track by $index">{{row[field.caption] }}</td>
</tr>
Vinay
quelle
Nur zur Verdeutlichung: Attribute, die in der Spur nach Ausdruck verwendet werden, müssen über die wiederholte Sammlung hinweg eindeutig sein. $ index ist eine Option. In den meisten Fällen ist es ausreichend, aber manchmal kann es nützlich sein, nach eindeutigen Attributen zu suchen (id, ...)
Martin Hlavňa
Dies setzt voraus, dass sich die Reihenfolge Ihrer Artikel niemals ändert. :)
ordentliches Codieren
3

So können Sie den $$ hashKey einfach aus dem Objekt entfernen:

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

$scope.myObject - Bezieht sich auf das Objekt, für das Sie die Operation ausführen möchten, dh entfernen Sie den $$ hashKey aus

$scope.myNewObject - Weisen Sie das geänderte Originalobjekt dem neuen Objekt zu, damit es bei Bedarf verwendet werden kann

Devner
quelle
Ich finde das unnötig komplex. Sie können einfach dieses einzelne Feld entfernen - oder jedes Feld, das mit $ beginnt. Aber wahrscheinlich müssen Sie nicht - sehen Sie die anderen Antworten.
Sevcsik
1

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

Angular ist ziemlich magisch, wenn die Leute es zum ersten Mal sehen. Automatische DOM-Aktualisierungen, wenn Sie eine Variable in Ihrem JS aktualisieren, und dieselbe Variable wird in Ihrer JS-Datei aktualisiert, wenn jemand ihren Wert im DOM aktualisiert. Dieselbe Funktionalität funktioniert über Seitenelemente und Controller hinweg.

Der Schlüssel zu all dem ist der $$ hashKey Angular, der an Objekte und Arrays angehängt wird, die in ng-Wiederholungen verwendet werden.

Dieser $$ hashKey sorgt für große Verwirrung bei Personen, die vollständige Objekte an eine API senden, die keine zusätzlichen Daten entfernt. Die API gibt für alle Ihre Anforderungen eine 400 zurück, aber dieser $$ hashKey wird nicht von Ihren Objekten entfernt.

Angular verwendet den $$ hashKey, um zu verfolgen, welche Elemente im DOM zu welchem ​​Element in einem Array gehören, das in einer ng-Wiederholung durchlaufen wird. Ohne den $$ hashKey hätte Angular keine Möglichkeit, Änderungen, die im JavaScript oder DOM auftreten, auf das Gegenstück anzuwenden, was eine der Hauptanwendungen für Angular ist.

Betrachten Sie dieses Array:

users = [  
    {
         first_name: "Tim"
         last_name: "Costa"
         email: "[email protected]"
    }
]

Wenn wir dies mit ng-repeat = "user in users" in eine Liste rendern würden, würde jedes Objekt darin einen $$ hashKey für Verfolgungszwecke von Angular erhalten. Hier sind zwei Möglichkeiten, um diesen $$ hashKey zu vermeiden.

Alfishan Aqeel
quelle