什么是$$hashKey添加到我的JSON。stringify结果

我试着查看他们文档的Mozilla JSON stringify页以及这里的SO和谷歌,但没有找到解释。我已经使用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"
}
]

我只是好奇$$hashkey属性到底是什么,因为我期望从stringify方法(即没有$$hashkey)中得到更类似于下面的东西:

[
{
"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
  • 春天3.0.4

我还在服务器端使用了Spring安全性3.0.7。

它没有引起我任何问题,但我想知道$$hashkey的原因和原因

171418 次浏览

它通常随ng-repeat指令而来。要做dom操作,AngularJS用特殊id标记对象。

这在Angular中很常见。例如,如果你使用ngResource获取对象,你的对象会嵌入所有的资源API,你会看到像$save等方法。对于cookie, AngularJS会添加一个属性__ngDebug。

Angular添加这个来跟踪你的更改,这样它就知道什么时候需要更新DOM。

如果你使用angular.toJson(obj)而不是JSON.stringify(obj),那么Angular会为你去掉这些内部使用的值。

此外,如果你将repeat表达式更改为使用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肯定不行。

如果您不想在数据中添加id,您可以通过数组中的索引来跟踪,这将导致项根据它们在数组中的位置而不是它们的值来确定键值。

是这样的:

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


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

在我的用例中(将结果对象提供给X2JS)是推荐的方法

data = angular.toJson(source);

帮助删除$$hashKey属性,但结果不能再被X2JS处理。

data = angular.copy(source);

也删除了$$hashKey属性,但结果仍然可用作X2JS的参数。

更新:从Angular v1.5开始,通过$index跟踪现在是标准语法,而不是使用link,因为它给了我一个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>

如果你使用的是Angular 1.3或更高版本,我建议你在ng-repeat中使用"track by"。如果你使用了"track by", Angular不会给数组中的对象添加"$$hashKey"属性。你还可以获得性能上的好处,如果数组中的某些东西发生了变化,angular不会为ng-repeat重新创建整个DOM结构,而是为数组中发生变化的值重新创建DOM的那一部分。

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

人们第一次看到Angular的时候,会觉得它很神奇。当你更新JS中的一个变量时,DOM会自动更新,当有人更新DOM中的值时,相同的变量也会在你的JS文件中更新。同样的功能也适用于页面元素和控制器。

这一切的关键是Angular附加到ng-repeat中使用的对象和数组的$$hashKey。

对于那些将完整对象发送到没有剥离额外数据的API的人来说,这个$$hashKey会引起很多困惑。API会为你的所有请求返回一个400,但是$$hashKey不会离开你的对象。

Angular使用$$hashKey来跟踪在ng-repeat中循环遍历的数组中,DOM中的哪些元素属于哪个元素。如果没有$$hashKey, Angular就无法将发生在JavaScript或DOM中的更改应用到对应的对象上,这是Angular的主要用途之一。

考虑这个数组:

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

如果我们使用ng-repeat="user in users"将其渲染为列表,其中的每个对象都会接收一个$$hashKey,用于Angular的跟踪。这里有两种方法来避免这个$$hashKey。

下面是简单地从对象中删除$$hashKey的方法:

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

$scope.myObject -指向你想要执行操作的对象,即从其中移除$$hashKey

$scope.myNewObject -将修改后的原始对象分配给新对象,以便在必要时使用