Che cos'è $$ hashKey aggiunto al mio risultato JSON.stringify


288

Ho provato a cercare nella pagina di stringify di Mozilla JSON dei loro documenti e qui su SO e Google, ma non ho trovato alcuna spiegazione. Ho usato JSOn per stringere molte volte ma non ho mai riscontrato questo risultato

Ho una serie di oggetti 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"
    }
]

in allegato al mio $scopee al fine di POSTutilizzarli come unico parametro ho usato il metodo JSON.stringify () e ho ottenuto quanto segue:

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

Sono solo curioso di sapere cos'è esattamente l'hashkey $$ poiché mi aspettavo qualcosa di più simile al seguente dal metodo stringify:

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

Non sono sicuro che sia un fattore, ma sto usando Angularjs 1.1.5, JQuery 1.8.2 and Spring 3.0.4 and Spring security 3.0.7 on the Server side

Non mi sta causando alcun problema, ma vorrei conoscere la causa e la ragione del $$hashkey


8
è aggiunto da angularjs
Arun P Johny il


69
invece di JSON.stringify usa angular.toJson ()
Arun P Johny,

Grazie ragazzi, se qualcuno vuole aggiungere la sua spiegazione come risposta sarei felice di accettare
jonnie

1
Questa risposta è un'ottima spiegazione .. stackoverflow.com/questions/12336897/…
Charlie Martin

Risposte:


530

Angular aggiunge questo per tenere traccia delle modifiche, quindi sa quando deve aggiornare il DOM.

Se si utilizza angular.toJson(obj)invece di JSON.stringify(obj)Angular, verranno eliminati questi valori di uso interno.

Inoltre, se si modifica l'espressione ripetuta per utilizzare il track by {uniqueProperty}suffisso, Angular non dovrà aggiungere $$hashKeyaffatto. Per esempio

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

Ricorda sempre che hai bisogno del "link". parte dell'espressione - tendo sempre a dimenticarlo. Basta track by hrefsicuramente non funzionerà.


Esistono test delle prestazioni su «track by» vs «$$ hashKey»? (UPD. Ok, l'ho
cercato su Google

Il tracciamento di @artuska per ID è molto semplice in quanto non è necessario calcolare alcun hash, basta riutilizzare gli ID esistenti o incrementare un contatore ...
Christophe Roussy,

3
e se hai un filtro da applicare, ecco l'ordine corretto:, item in somelist | filter:somefilter track by item.keynon scrivere il filtro alla fine della riga!
Lewen,

1
Nota! Stavo usando un array con un metodo clone che ha copiato gli elementi inseriti in un array, che è stato poi reso da una ripetizione ng. Stavo ottenendo errori angolari di "chiave duplicata" quando usavo JSON.parse (JSON.stringify (obj)) per clonare il mio elemento. Utilizzando JSON.parse (angular.toJson (obj)); cose fisse. Grazie!
SAL

1
È inoltre possibile utilizzare la funzionalità Rilegatura singola utilizzando i due punti :: per impedirne l'aggiornamento se si stanno visualizzando solo i dati. <a ng-href="link.href"> {{:: link.title}} </a>
phil

70

Nel mio caso d'uso (che fornisce l'oggetto risultante a X2JS) l'approccio raccomandato

data = angular.toJson(source);

aiuta a rimuovere le $$hashKeyproprietà, ma il risultato non può più essere elaborato da X2JS .

data = angular.copy(source);

rimosse anche le $$hashKeyproprietà, ma il risultato è rimasto utilizzabile come parametro per X2JS.


37

Normalmente viene fornito con la direttiva ng-repeat. Per eseguire la manipolazione dom AngularJS contrassegna gli oggetti con un ID speciale.

Questo è comune con Angular. Ad esempio se ottieni oggetto con ngResource il tuo oggetto incorporerà tutte le API delle risorse e vedrai metodi come $ save, ecc. Con i cookie anche AngularJS aggiungerà una proprietà __ngDebug.


come devo rimuovere queste proprietà? Angular fornisce un modo per farlo?
Nilesh,

1
I modelli angolari si rompono se provi a rimuovere quella proprietà, ti consiglio di copiare la variabile. Vedi la risposta di @ David-Boike su come filtrare l'hashkey
Josue Alexander Ibarra,

23

Se non si desidera aggiungere ID ai dati, è possibile tenere traccia dell'indice nell'array, il che provocherà la digitazione degli elementi in base alla loro posizione nell'array anziché al loro valore.

Come questo:

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

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

Ciò presuppone che l'ordine dei tuoi articoli non cambierà mai. :)
neatcoding il

8

Se stai usando Angular 1.3 o versioni successive, ti consiglio di usare "track by" nel tuo ng-repeat. Angular non aggiunge una proprietà "$$ hashKey" agli oggetti nell'array se si utilizza "track by". Ottieni anche vantaggi in termini di prestazioni, se qualcosa nel tuo array cambia, angolare non ricrea l'intera struttura DOM per il tuo ng-repeat, ma ricrea la parte del DOM per i valori nel tuo array che sono stati modificati.


4

Aggiornamento: Da Angular v1.5, track by $indexè ora la sintassi standard invece di utilizzare il link in quanto mi ha dato un ng-repeaterrore dupes.

Mi sono imbattuto in questo per un nidificato ng-repeate il seguito ha funzionato.

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

Giusto per chiarire: l'attributo usato nel tracciare per espressione deve essere unico nella raccolta ripetuta. $ index è un'opzione. Nella maggior parte dei casi è sufficiente, ma a volte potresti trovare utile tracciare per attributo univoco. (Id, ...)
Martin Hlavňa

Ciò presuppone che l'ordine dei tuoi articoli non cambierà mai. :)
neatcoding il

3

Ecco come è possibile rimuovere facilmente $$ hashKey dall'oggetto:

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

$scope.myObject - Si riferisce all'oggetto su cui si desidera eseguire l'operazione, ad esempio rimuovere $$ hashKey da

$scope.myNewObject - Assegna l'oggetto originale modificato al nuovo oggetto in modo che possa essere utilizzato secondo necessità


Lo trovo inutilmente complesso. Potresti semplicemente rimuovere quel singolo campo o ogni campo che inizia con $. Ma probabilmente non è necessario: vedi le altre risposte.
sevcsik,

1

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

Angular è piuttosto magico la prima volta che la gente lo vede. Aggiornamenti DOM automatici quando aggiorni una variabile nel tuo JS e la stessa variabile si aggiorna nel tuo file JS quando qualcuno aggiorna il suo valore nel DOM. Questa stessa funzionalità funziona tra gli elementi della pagina e tra i controller.

La chiave di tutto ciò è che $$ hashKey Angular si collega agli oggetti e alle matrici utilizzate nelle ripetizioni di ng.

Questo hashKey $$ crea molta confusione per le persone che inviano oggetti completi a un'API che non rimuove i dati extra. L'API restituirà un 400 per tutte le tue richieste, ma quel hashKey $$ non andrà via dai tuoi oggetti.

Angular usa $$ hashKey per tenere traccia di quali elementi nel DOM appartengono a quale elemento in un array che viene ripetuto in loop in una ripetizione ng. Senza $$ hashKey Angular non ci sarebbe modo di applicare le modifiche che si verificano in JavaScript o DOM alla loro controparte, che è uno degli usi principali di Angular.

Considera questo array:

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

Se lo rendessimo in un elenco usando ng-repeat = "utente negli utenti", ogni oggetto in esso riceverebbe un hashKey $$ per scopi di tracciamento da Angular. Ecco due modi per evitare questo $$ hashKey.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.