Co to jest $$ hashKey dodany do mojego wyniku JSON.stringify


289

Próbowałem przeglądać na swoich stronach dokumentacyjnych Mozilli JSON strify, a także tutaj w SO i Google, ale nie znalazłem wyjaśnienia. Używałem JSOn stringify wiele razy, ale nigdy nie natknąłem się na ten wynik

Mam tablicę obiektów 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"
    }
]

dołączony do mojego $scopei aby POSTje jako jeden parametr użyłem metody JSON.stringify () i otrzymuję:

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

Jestem tylko ciekawy, co to właściwie jest hash $$, ponieważ spodziewałem się czegoś bardziej podobnego do następującego po metodzie 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"
        }
    }
]

Nie jestem pewien, czy to czynnik, ale używam Angularjs 1.1.5, JQuery 1.8.2 and Spring 3.0.4 and Spring security 3.0.7 on the Server side

Nie powoduje to żadnych problemów, ale chciałbym poznać przyczynę i przyczynę $$hashkey


8
dodaje go angularjs
Arun P Johny


69
zamiast JSON.stringify użyj angular.toJson ()
Arun P. Johny

Dzięki Chłopaki, jeśli ktoś chce dodać twoje wyjaśnienie jako odpowiedź, chętnie bym je zaakceptował
jonnie

1
Ta odpowiedź jest doskonałym wyjaśnieniem. Stackoverflow.com/questions/12336897/
Charlie Martin

Odpowiedzi:


531

Angular dodaje to, aby śledzić zmiany, dzięki czemu wie, kiedy musi zaktualizować DOM.

Jeśli użyjesz angular.toJson(obj)zamiast JSON.stringify(obj)tego, Angular usunie te wewnętrzne wartości dla ciebie.

Ponadto, jeśli zmienisz wyrażenie wielokrotne w celu użycia track by {uniqueProperty}przyrostka, Angular nie będzie musiał wcale dodawać $$hashKey. Na przykład

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

Pamiętaj tylko, że potrzebujesz „linku”. część wyrażenia - zawsze o tym zapominam. Na track by hrefpewno nie zadziała.


Czy są jakieś testy wydajności dotyczące opcji „śledź według” w porównaniu z „$$ hashKey”? (UPD. Ok, przejrzałem go i „utwór według” jest bardziej
preferowany

Śledzenie @artuska według identyfikatora jest bardzo proste, ponieważ nie trzeba obliczać żadnych skrótów, wystarczy ponownie użyć istniejących identyfikatorów lub zwiększyć licznik ...
Christophe Roussy

3
a jeśli masz filtr do zastosowania, oto właściwa kolejność: item in somelist | filter:somefilter track by item.keynie pisz filtra na końcu wiersza!
Lewen

1
Uwaga! Używałem tablicy metodą klonowania, która skopiowała, a następnie wstawiła elementy do tablicy, która została następnie zrenderowana przez powtórzenie ng. Podczas używania pliku JSON.parse (JSON.stringify (obj)) otrzymywałem błędy kątowe „duplikowania klucza” do klonowania mojego elementu. Korzystanie z JSON.parse (angular.toJson (obj)); naprawione rzeczy. Dzięki!
SAL

1
Możesz także użyć funkcji One Time Binding, używając podwójnego dwukropka ::, aby uniemożliwić jej aktualizację, jeśli wyświetlasz tylko dane. <a ng-href="link.href"> {{:: link.title}} </a>
phil

70

W moim przypadku użycia (podawanie wynikowego obiektu do X2JS) zalecane podejście

data = angular.toJson(source);

pomagają usunąć $$hashKeywłaściwości, ale wynik nie może być już przetworzony przez X2JS .

data = angular.copy(source);

usunął również $$hashKeywłaściwości, ale wynik pozostał użyteczny jako parametr dla X2JS.


37

Zwykle pochodzi z dyrektywą ng-repeat. Aby wykonać manipulację domem, AngularJS zaznacza obiekty specjalnym identyfikatorem.

Jest to typowe dla Angulara. Na przykład, jeśli dostaniesz obiekt za pomocą ngResource, twój obiekt osadzi wszystkie API zasobów, a zobaczysz metody takie jak $ save, itp. W przypadku ciasteczek też AngularJS doda właściwość __ngDebug.


jak powinienem usunąć te właściwości? Czy kąt pozwala to zrobić?
Nilesh

1
Modele kątowe zepsują się, jeśli spróbujesz usunąć tę właściwość, zalecam skopiowanie zmiennej. Zobacz odpowiedź @ David-Boike na temat filtrowania haszyszu
Josue Alexander Ibarra

23

Jeśli nie chcesz dodawać identyfikatorów do swoich danych, możesz śledzić według indeksu w tablicy, co spowoduje, że elementy będą kluczowane przez ich pozycję w tablicy zamiast ich wartości.

Lubię to:

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

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

Wymaga to założenia, że ​​kolejność twoich przedmiotów nigdy się nie zmieni. :)
neatcoding

8

Jeśli używasz Angulara 1.3 lub nowszego, zalecamy użycie opcji „śledź przez” w powtórzeniu ng. Angular nie dodaje właściwości „$$ hashKey” do obiektów w tablicy, jeśli używasz opcji „śledź według”. Uzyskujesz również korzyści w zakresie wydajności, jeśli coś w tablicy się zmieni, kąt nie odtworzy całej struktury DOM dla twojego powtórzenia ng, zamiast tego odtworzy część DOM dla wartości w tablicy, które uległy zmianie.


4

Aktualizacja: Od Angular v1.5, śledzenie według $indexjest teraz standardową składnią zamiast używania linku, ponieważ dał mi ng-repeatbłąd duplikatów.

Wpadłem na to dla zagnieżdżonego ng-repeati poniższe zadziałało.

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

Tylko dla wyjaśnienia - atrybut użyty w śledzeniu według wyrażenia musi być unikalny w całej powtarzanej kolekcji. Indeks $ jest jedną z opcji. W większości przypadków jest to wystarczające, ale czasem przydatne może być śledzenie według unikalnego atrybutu. (Id, ...)
Martin Hlavňa

Wymaga to założenia, że ​​kolejność twoich przedmiotów nigdy się nie zmieni. :)
neatcoding

3

Oto, jak możesz łatwo usunąć $$ hashKey z obiektu:

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

$scope.myObject - Odnosi się do obiektu, na którym chcesz wykonać operację, tj. Usunąć klucz hash $$

$scope.myNewObject - Przypisz zmodyfikowany oryginalny obiekt do nowego obiektu, aby można go było użyć w razie potrzeby


Uważam to za niepotrzebnie skomplikowane. Możesz po prostu usunąć to pojedyncze pole - lub każde pole zaczynające się na $. Ale prawdopodobnie nie musisz - zobacz inne odpowiedzi.
sevcsik

1

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

Angular jest dość magiczny, kiedy ludzie go widzą po raz pierwszy. Automatyczne aktualizacje DOM po aktualizacji zmiennej w JS, a ta sama zmienna zostanie zaktualizowana w pliku JS, gdy ktoś zaktualizuje jej wartość w DOM. Ta sama funkcjonalność działa w przypadku elementów strony i kontrolerów.

Kluczem do tego wszystkiego jest $$ hashKey Angular dołączany do obiektów i tablic używanych w powtórzeniach ng.

Ten $$ hashKey powoduje wiele zamieszania dla osób, które wysyłają pełne obiekty do interfejsu API, który nie usuwa dodatkowych danych. API zwróci 400 dla wszystkich twoich żądań, ale ten hashKey $$ po prostu nie odejdzie od twoich obiektów.

Angular używa $$ hashKey do śledzenia, które elementy w DOM należą do którego elementu w tablicy, która jest zapętlana w powtórzeniu ng. Bez $$ hashKey Angular nie miałby możliwości zastosowania zmian, które wystąpiłyby w JavaScript lub DOM w ich odpowiedniku, co jest jednym z głównych zastosowań Angulara.

Rozważ tę tablicę:

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

Jeśli wyrenderowaliśmy to na liście za pomocą ng-repeat = "użytkownik w użytkownikach", każdy obiekt w nim otrzymałby $$ hashKey do celów śledzenia od Angular. Oto dwa sposoby uniknięcia tego hashKey $$.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.