Что $$ hashKey добавлено в мой результат 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

Jonnie
источник
8
добавлено angularjs
Арун П Джонни
69
вместо JSON.stringify используйте angular.toJson ()
Арун П. Джонни,
Спасибо, ребята, если кто-то захочет добавить ваше объяснение в качестве ответа, я был бы рад принять
Джонни
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 по идентификатору очень просто, так как не нужно вычислять хэши, вы просто повторно используете существующие идентификаторы или увеличиваете счетчик ...
Кристоф Руссси,
3
и если у вас есть фильтр для применения, вот правильный порядок: item in somelist | filter:somefilter track by item.keyне пишите фильтр в конце строки!
Lewen
1
Заметка! Я использовал массив с методом клонирования, который копировал и вставлял элементы в массив, который затем обрабатывался с помощью ng-repeat. Я получал угловые ошибки «дублирующий ключ» при использовании JSON.parse (JSON.stringify (obj)) для клонирования моего элемента. Использование JSON.parse (angular.toJson (obj)); фиксированные вещи. Спасибо!
SAL
1
Вы также можете использовать функцию однократного связывания, используя двойное двоеточие ::, чтобы предотвратить его обновление, если вы только отображаете данные. <a ng-href="link.href"> {{:: link.title}} </a>
Фил,
70

В моем случае использования (передача полученного объекта в X2JS) рекомендуемый подход

data = angular.toJson(source);

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

data = angular.copy(source);

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

rob2universe
источник
37

Обычно он поставляется с директивой ng-repeat. Для манипулирования домом AngularJS помечает объекты со специальным идентификатором.

Это общее с Angular. Например, если вы получите объект с помощью ngResource, ваш объект будет встраивать все API ресурсов, и вы увидите такие методы, как $ save и т. Д. Также и с файлами cookie AngularJS добавит свойство __ngDebug.

Томас Понс
источник
как я должен удалить эти свойства? Angular предоставляет какой-либо способ сделать это?
Nilesh
1
Угловые модели сломаются, если вы попытаетесь удалить это свойство, я рекомендую скопировать переменную. См. Ответ @ David-Boike о том, как отфильтровать хешки
Alexander Ibarra
23

Если вы не хотите добавлять идентификаторы в свои данные, вы можете отслеживать по индексу в массиве, что приведет к тому, что элементы будут обозначены позицией в массиве, а не их значением.

Как это:

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

<li ng-repeat="item in myArray track by $index">
Майкл Фальк Ведельгорд
источник
Это требует предположения, что порядок ваших товаров никогда не изменится. :)
neatcoding
8

Если вы используете Angular 1.3 или выше, я рекомендую использовать «track by» в вашем ng-repeat. Angular не добавляет свойство $$ hashKey к объектам в вашем массиве, если вы используете «track by». Вы также получаете выигрыш в производительности, если что-то в вашем массиве изменяется, angular не воссоздает всю структуру DOM для вашего ng-repeat, вместо этого он воссоздает часть DOM для значений в вашем массиве, которые изменились.

Аджай Уллал
источник
4

Обновление: Начиная с Angular v1.5, отслеживание по $indexтеперь является стандартным синтаксисом, а не использованием ссылки, поскольку это дало мне ng-repeatошибку dupes.

Я столкнулся с этим для вложенного 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
Это требует предположения, что порядок ваших товаров никогда не изменится. :)
neatcoding
3

Вот как вы можете легко удалить $$ hashKey из объекта:

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

$scope.myObject - Относится к объекту, над которым вы хотите выполнить операцию, т.е. удалите $$ hashKey из

$scope.myNewObject - Назначьте измененный исходный объект новому объекту, чтобы его можно было использовать по мере необходимости.

Devner
источник
Я нахожу это излишне сложным. Вы можете просто удалить это единственное поле - или каждое поле, начинающееся с $. Но, вероятно, вам не нужно - смотрите другие ответы.
17
1

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

Angular довольно волшебен, когда люди впервые видят его. Автоматическое обновление DOM, когда вы обновляете переменную в вашем JS, и эта же переменная будет обновляться в вашем файле JS, когда кто-то обновляет его значение в DOM. Эта же функциональность работает для всех элементов страницы и контроллеров.

Ключом ко всему этому является привязка $$ hashKey Angular к объектам и массивам, используемым в ng-повторениях.

Этот $$ hashKey вызывает путаницу у людей, которые отправляют полные объекты в API, который не удаляет лишние данные. API вернет 400 для всех ваших запросов, но этот $$ hashKey просто не уйдет от ваших объектов.

Angular использует $$ hashKey для отслеживания того, какие элементы в DOM принадлежат тому или иному элементу в массиве, который проходит через ng-repeat. Без $$ hashKey Angular не сможет применить изменения, происходящие в JavaScript или DOM, к своему аналогу, что является одним из основных применений Angular.

Рассмотрим этот массив:

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

Если мы отобразим это в список, используя ng-repeat = "user in users", каждый объект в нем получит $$ hashKey для отслеживания в Angular. Вот два способа избежать этого $$ hashKey.

Alfishan Aqeel
источник