Quelle est la clé de hachage $$ ajoutée à mon résultat JSON.stringify

288

J'ai essayé de chercher sur la page Mozilla JSON stringify de leurs documents ainsi qu'ici sur SO et Google mais je n'ai trouvé aucune explication. J'ai utilisé JSOn stringify plusieurs fois mais je n'ai jamais rencontré ce résultat

J'ai un tableau d'objets 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"
    }
]

attaché à mon $scopeet pour POSTeux en tant que paramètre, j'ai utilisé la méthode JSON.stringify () et j'obtiens ce qui suit:

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

Je suis juste curieux de savoir ce qu'est exactement le hashkey $$ car je m'attendais à quelque chose de plus similaire à ce qui suit de la méthode 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"
        }
    }
]

Je ne sais pas si c'est un facteur mais j'utilise Angularjs 1.1.5, JQuery 1.8.2 and Spring 3.0.4 and Spring security 3.0.7 on the Server side

Cela ne me pose aucun problème, mais j'aimerais connaître la cause et la raison de la $$hashkey

jonnie
la source
8
il est ajouté par angularjs
Arun P Johny
69
au lieu de JSON.stringify, utilisez angular.toJson ()
Arun P Johny
Merci les gars, si quelqu'un veut ajouter votre explication comme réponse, je serais heureux d'accepter
jonnie
1
Cette réponse est une excellente explication .. stackoverflow.com/questions/12336897/…
Charlie Martin

Réponses:

530

Angular ajoute ceci pour garder une trace de vos modifications, afin qu'il sache quand il doit mettre à jour le DOM.

Si vous utilisez angular.toJson(obj)au lieu de JSON.stringify(obj)alors Angular supprimera ces valeurs à usage interne pour vous.

De plus, si vous modifiez votre expression de répétition pour utiliser le track by {uniqueProperty}suffixe, Angular n'aura pas du tout à ajouter $$hashKey. Par exemple

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

Rappelez-vous toujours que vous avez besoin du "lien". une partie de l'expression - j'ai toujours tendance à l'oublier. Ne fonctionnera track by hrefsûrement pas.

David Boike
la source
Existe-t-il des tests de performance sur «track by» vs «$$ hashKey»? (UPD. Ok, je l'ai googlé et «track by» est plus
préférable
Le suivi @artuska par identifiant est très simple car aucun hachage ne doit être calculé, vous devez simplement réutiliser les identifiants existants ou incrémenter un compteur ...
Christophe Roussy
3
et si vous avez un filtre à appliquer, voici le bon ordre: item in somelist | filter:somefilter track by item.keyn'écrivez pas le filtre à la fin de la ligne!
Lewen
1
Remarque! J'utilisais un tableau avec une méthode de clonage qui copiait puis insérait des éléments dans un tableau, qui était ensuite rendu par une répétition ng. J'obtenais des erreurs angulaires de «clé en double» lors de l'utilisation de JSON.parse (JSON.stringify (obj)) pour cloner mon élément. Utilisation de JSON.parse (angular.toJson (obj)); les choses fixes. Merci!
SAL
1
Vous pouvez également utiliser la fonctionnalité de liaison unique à l'aide de deux points: pour l'empêcher de se mettre à jour si vous affichez uniquement des données. <a ng-href="link.href"> {{:: link.title}} </a>
phil
70

Dans mon cas d'utilisation (alimentation de l'objet résultant vers X2JS), l'approche recommandée

data = angular.toJson(source);

aide à supprimer les $$hashKeypropriétés, mais le résultat ne peut alors plus être traité par X2JS .

data = angular.copy(source);

a également supprimé les $$hashKeypropriétés, mais le résultat est resté utilisable comme paramètre pour X2JS.

rob2universe
la source
37

Il est généralement livré avec la directive ng-repeat. Pour effectuer une manipulation dom, AngularJS marque les objets avec un identifiant spécial.

C'est commun avec Angular. Par exemple, si vous obtenez un objet avec ngResource, votre objet incorporera toutes les API de ressources et vous verrez des méthodes comme $ save, etc. Avec les cookies aussi, AngularJS ajoutera une propriété __ngDebug.

Thomas Pons
la source
comment dois-je supprimer ces propriétés? L'angulaire fournit-il un moyen de le faire?
Nilesh
1
Les modèles angulaires se briseront si vous essayez de supprimer cette propriété, je recommande de copier la variable. Voir la réponse de @ David-Boike sur la façon de filtrer le hashkey
Josue Alexander Ibarra
23

Si vous ne souhaitez pas ajouter d'ID à vos données, vous pouvez effectuer le suivi par l'index dans le tableau, ce qui entraînera la saisie des éléments par leur position dans le tableau au lieu de leur valeur.

Comme ça:

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

<li ng-repeat="item in myArray track by $index">
Michael Falck Wedelgård
la source
Cela nécessite l'hypothèse que l'ordre de vos articles ne changera jamais. :)
neatcoding
8

Si vous utilisez Angular 1.3 ou supérieur, je vous recommande d'utiliser "track by" dans votre ng-repeat. Angular n'ajoute pas de propriété "$$ hashKey" aux objets de votre tableau si vous utilisez "track by". Vous obtenez également des avantages en termes de performances, si quelque chose dans votre tableau change, angular ne recrée pas la structure DOM entière pour votre ng-repeat, il recrée à la place la partie du DOM pour les valeurs de votre tableau qui ont changé.

Ajay Ullal
la source
4

Mise à jour: à partir d'Angular v1.5, track by $indexest maintenant la syntaxe standard au lieu d'utiliser le lien car cela m'a donné une ng-repeaterreur de dupes.

Je suis tombé sur cela pour un nid ng-repeatet le ci-dessous a fonctionné.

<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
la source
Juste pour clarifier - l'attribut utilisé dans la piste par expression doit être unique dans la collection répétée. $ index est une option. Dans la plupart des cas, cela suffit, mais il peut parfois
s'avérer
Cela nécessite l'hypothèse que l'ordre de vos articles ne changera jamais. :)
neatcoding
3

Voici comment supprimer facilement la clé de hachage $$ de l'objet:

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

$scope.myObject - Fait référence à l'objet sur lequel vous souhaitez effectuer l'opération, c'est-à-dire supprimez la clé de hachage $$ de

$scope.myNewObject - Attribuez l'objet d'origine modifié au nouvel objet afin qu'il puisse être utilisé si nécessaire

Devner
la source
Je trouve cela inutilement complexe. Vous pouvez simplement supprimer ce champ unique - ou tous les champs commençant par $. Mais vous n'avez probablement pas besoin de - voir les autres réponses.
sevcsik
1

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

Angular est assez magique la première fois que les gens le voient. Les mises à jour DOM automatiques lorsque vous mettez à jour une variable dans votre JS, et la même variable sera mise à jour dans votre fichier JS lorsque quelqu'un met à jour sa valeur dans le DOM. Cette même fonctionnalité fonctionne sur tous les éléments de la page et sur tous les contrôleurs.

La clé de tout cela est l'attachement $$ hashKey Angular aux objets et aux tableaux utilisés dans ng-repeats.

Cette clé de hachage $$ provoque beaucoup de confusion pour les personnes qui envoient des objets complets à une API qui ne supprime pas les données supplémentaires. L'API renverra un 400 pour toutes vos demandes, mais cette clé de hachage $$ ne s'éloignera pas de vos objets.

Angular utilise la clé de hachage $$ pour garder une trace des éléments du DOM qui appartiennent à quel élément d'un tableau en boucle dans une répétition ng. Sans le $$ hashKey Angular, il n'y aurait aucun moyen d'appliquer les modifications qui se produisent dans le JavaScript ou le DOM à leur homologue, ce qui est l'une des principales utilisations d'Angular.

Considérez ce tableau:

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

Si nous rendions cela dans une liste en utilisant ng-repeat = "user in users", chaque objet qu'il contient recevrait une clé de hachage $$ à des fins de suivi d'Angular. Voici deux façons d'éviter ce $$ hashKey.

alfishan aqeel
la source