Що таке $$ хеш-ключ, доданий до мого результату JSON.stringify


289

Я спробував подивитися на зазирнути на сторінку Mozilla JSON, що розшифровував їх документи, а також тут на SO та Google, але не знайшов пояснення. Я багато разів використовував JSOn stringify, але ніколи не стикався з цим результатом

У мене є масив об'єктів 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і для того, щоб POSTяк один параметр я використав метод 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:

[
    {
        "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
Arun P Johny

Дякую, хлопці, якщо хтось хоче додати ваше пояснення як відповідь, я би радий прийняти
jonnie

1
Ця відповідь є чудовим поясненням .. stackoverflow.com/questions/12336897/…
Чарлі Мартін

Відповіді:


531

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

Відстеження @artuska за допомогою id дуже просте, тому що не потрібно обчислювати хеш, ви просто повторно використовуєте існуючі ідентифікатори або збільшуєте лічильник ...
Christophe Roussy

3
і якщо у вас є фільтр, який потрібно застосувати, ось правильний порядок: item in somelist | filter:somefilter track by item.keyне пишіть фільтр у кінці рядка!
Lewen

1
Примітка! Я використовував масив методом клонування, який скопіював, а потім вставив елементи в масив, який потім був наданий ng-повтором. Під час використання JSON.parse (JSON.stringify (obj)) я отримував кутові помилки "дубліката ключа" для клонування мого елемента. Використання JSON.parse (angular.toJson (obj)); виправлені речі. Дякую!
SAL

1
Ви також можете скористатися функцією "Одночасне прив'язування", використовуючи подвійну двокрапку ::, щоб запобігти її оновленню, якщо ви відображаєте лише дані. <a ng-href="link.href"> {{:: link.title}} </a>
phil

70

У моєму випадку використання (подача отриманого об'єкта в X2JS) рекомендований підхід

data = angular.toJson(source);

допомагають видалити $$hashKeyвластивості, але результат X2JS більше не може оброблятися .

data = angular.copy(source);

видалено також $$hashKeyвластивості, але результат залишився корисним як параметр для X2JS.


37

Як правило, він постачається з директивою ng-repeat. Для маніпуляції з будинком AngularJS позначає об'єкти зі спеціальним ідентифікатором.

Це спільно з Angular. Наприклад, якщо ви отримаєте об'єкт з ngResource, ваш об’єкт вбудує весь API ресурсу, і ви побачите такі методи, як $ save тощо. І для файлів cookie AngularJS додасть властивість __ngDebug.


як я повинен видалити ці властивості? Чи передбачений кутовий спосіб зробити це?
Нілеш

1
Кутові моделі зламаються, якщо ви спробуєте вилучити цю властивість, рекомендую скопіювати змінну. Дивіться відповідь @ David-Boike про те, як відфільтрувати хешкей
Олександр Ібарра

23

Якщо ви не хочете додавати ідентифікатори до своїх даних, ви можете відстежувати за індексом у масиві, що призведе до того, що елементи будуть вводитись за допомогою їх положення в масиві замість їх значення.

Подобається це:

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

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

Це вимагає припущення, що порядок ваших товарів ніколи не зміниться. :)
чисте кодування

8

Якщо ви використовуєте Angular 1.3 або вище, я рекомендую вам використовувати «track by» у своєму ng-повторі. Angular не додає властивості "$$ hashKey" до об'єктів у вашому масиві, якщо ви використовуєте "слід від". Ви також отримуєте переваги від продуктивності, якщо щось у вашому масиві змінюється, angular не відтворює всю структуру DOM для вашого ng-повтору, а натомість відтворює частину 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>

Просто для уточнення - атрибут, що використовується у сліді за виразом, повинен бути унікальним у повторному зібранні. $ index - це один із варіантів. У більшості випадків цього достатньо, але іноді вам може бути корисно відслідковувати унікальний атрибут. (Id, ...)
Martin Hlavňa

Це вимагає припущення, що порядок ваших товарів ніколи не зміниться. :)
чисте кодування

3

Ось як ви можете легко видалити $$ хеш-ключ із об’єкта:

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

$scope.myObject - Посилається на об'єкт, над яким потрібно виконати операцію, тобто видалити з $$ hashKey

$scope.myNewObject - Призначте модифікований оригінальний об'єкт новому об'єкту, щоб він міг бути використаний у міру необхідності


Я вважаю це зайвим складним. Ви можете просто видалити це одне поле - або кожне поле, починаючи з $. Але, напевно, не потрібно - дивіться інші відповіді.
sevcsik

1

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

Кутовий досить чарівний перший раз, коли люди це бачать. Автоматичне оновлення DOM, коли ви оновлюєте змінну в JS, і ця сама змінна буде оновлена ​​у вашому файлі JS, коли хтось оновлює її значення в DOM. Цей самий функціонал працює як на сторінках, так і на контролерах.

Ключовим у всьому цьому є $$ hashKey Angular, що додається до об'єктів та масивів, що використовуються у ng-повторах.

Цей $$ хеш-ключ викликає багато плутанини у людей, які надсилають повні об’єкти в API, який не позбавляє зайвих даних. API поверне 400 для всіх ваших запитів, але цей $$ hashKey просто не піде від ваших об'єктів.

Angular використовує хеш-ключ $$, щоб відслідковувати, які елементи в DOM належать до того елемента в масиві, який пробирається через ng-повтор. Без $$ hashKey Angular не було б можливості застосувати зміни, що відбуваються в JavaScript або DOM, до їх аналога, що є одним з основних напрямків використання Angular.

Розглянемо цей масив:

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

Якщо ми перевели це в список, використовуючи ng-repe = "користувач у користувачах", кожен об'єкт в ньому отримає $$ хеш-ключ для цілей відстеження від Angular. Ось два способи уникнути цього $$ хеш-ключа.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.