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


288

我尝试查看他们文档的Mozilla JSON字符串化页面以及SO和Google上的内容,但没有找到解释。我已经使用JSOn字符串化很多次了,但从未遇到过这个结果

我有一个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方法获得与以下类似的东西:

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


69
代替JSON.stringify使用angular.toJson()
Arun P Johny

谢谢你们,如果有人想添加您的解释作为答案,我很乐意接受
jonnie 2013年

1
这个答案是一个很好的解释。 stackoverflow.com/questions/12336897/...
查理·马丁

Answers:


530

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。好吧,我用Google搜索了它,更
喜欢

@artuska通过ID进行跟踪非常简单,因为无需计算哈希即可,您只需重复使用现有ID或增加一个计数器即可……
Christophe Roussy 2015年

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 2016年

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指令。要进行dom操作,AngularJS会使用特殊ID标记对象。

这在Angular中很常见。例如,如果您使用ngResource获取对象,则您的对象将嵌入所有资源API,并且您将看到$ save之类的方法。同样使用Cookie,AngularJS还将添加属性__ngDebug。


我应该如何删除这些属性?请问角度提供任何方式做到这一点?
Nilesh 2014年

1
如果尝试删除该属性,则角度模型会损坏,我建议复制该变量。参见@ David-Boike关于如何过滤井号的答案
Josue Alexander Ibarra

23

如果您不想在数据中添加ID,则可以按数组中的索引进行跟踪,这将导致按其在数组中的位置而不是其值来键入项。

像这样:

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

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

这就需要假设您的项目顺序永远不会改变。:)
neatcoding

8

如果您使用的是Angular 1.3或更高版本,建议您在ng-repeat中使用“ track by”。如果您使用“ track by”,Angular不会在数组中的对象上添加“ $$ hashKey”属性。您还可以获得性能上的好处,如果数组中的某些内容发生更改,angular不会为ng-repeat重新创建整个DOM结构,而是为数组中已更改的值重新创建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,...)
MartinHlavňa17年

这就需要假设您的项目顺序永远不会改变。:)
neatcoding

3

这是您可以轻松地从对象中删除$$ hashKey的方法:

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

$scope.myObject -引用要在其上执行操作的对象,即从中删除$$ hashKey

$scope.myNewObject -将修改后的原始对象分配给新对象,以便可以根据需要使用


我发现这不必要地复杂。您可以删除单个字段-或以$开头的每个字段。但也许您不需要-查看其他答案。
sevcsik

1

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

Angular在人们第一次看到它时就非常神奇。当您在JS中更新变量时,DOM会自动更新,而当有人在DOM中更新其值时,相同的变量也会在JS文件中更新。相同的功能适用于页面元素和控制器。

所有这些的关键是$$ hashKey Angular附加到ng-repeats中使用的对象和数组。

对于将完整对象发送到不剥离额外数据的API的人们,此$$ hashKey引起了很多混乱。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的方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.