角度怪异:一个对象属性如何更改两个不同对象上的属性? [英] Angular weirdness: how can one object attribute change an attribute on two different objects?
问题描述
我正在使用Angularjs建立一个网站,其中有一个对象列表:
I'm building a website using Angularjs in which I've got a list of objects:
$scope.fieldsToShow = [
{
"fields": {},
"type": "LOGGED_IN"
},
{
"fields": {},
"type": "PERSONAL",
"user": 2,
"name": "Rick Astley"
}
];
然后我将其中一个对象选择为变量:
I then select one of the objects into a variable:
var $scope.currentObject = $scope.fieldsToShow[1];
让用户使用某些复选框进行更改:
to let the user change it using the some checkboxes:
<input ng-model="currentObject.fields.a" type="checkbox">
会同时更改 $ scope.currentObject
:
{
"fields": {
"a": true
},
"type": "PERSONAL",
"user": 2,
"name": "Rick Astley"
}
和 $ scope.fieldsToShow
中的原始对象:
$scope.fieldsToShow = [
{
"fields": {},
"type": "LOGGED_IN"
},
{
"fields": {
"a": true
},
"type": "PERSONAL",
"user": 2,
"name": "Rick Astley"
}
];
然后将 $ scope.currentObject
更改为数组中的第一个对象:
I then change the $scope.currentObject
to the first object in the array:
$scope.currentObject = $scope.fieldsToShow[0];
,然后再次单击该复选框.正如预期的那样,还会在 $ scope.fieldsToShow
列表中第一个对象的fields对象中添加"a":true
.到目前为止,一切都很好.
and I click the checkbox again. As expected this also adds "a": true
to the fields object of the first object in the $scope.fieldsToShow
list. So far so good.
我现在想在 fields
对象中添加一个对象.所以我创建了另一个复选框:
I now want to add an object within the fields
object. So I created another checkbox:
<input ng-model="currentObject.fields.anInnerObject.val" type="checkbox">
然后我再次更改为PERSONAL对象( $ scope.currentObject = $ scope.fieldsToShow [1];
),然后单击复选框.正如预期的那样,这会同时更改 $ scope.currentObject
:
I then change to the PERSONAL object again ($scope.currentObject = $scope.fieldsToShow[1];
) and click the checkbox. As expected this changes both the $scope.currentObject
:
{
"fields": {
"anInnerObject": {
"val": true
}
},
"type": "PERSONAL",
"user": 2,
"name": "Rick Astley"
}
和 $ scope.fieldsToShow
中的原始对象:
$scope.fieldsToShow = [
{
"fields": {},
"type": "LOGGED_IN"
},
{
"fields": {
"anInnerObject": {
"val": true
}
},
"type": "PERSONAL",
"user": 2,
"name": "Rick Astley"
}
];
然后我再次更改为 LOGGED_IN
对象( $ scope.currentObject = $ scope.fieldsToShow [0];
),然后再次单击复选框.这就是棘手的地方.如预期的那样,它更改了 $ scope.currentObject
:
I then change to the LOGGED_IN
object again ($scope.currentObject = $scope.fieldsToShow[0];
) and click the checkbox again. And here is where it gets tricky. As expected it changes the $scope.currentObject
:
{
"fields": {
"anInnerObject": {
"val": true
}
},
"type": "LOGGED_IN",
}
它还更改了 $ scope.fieldsToShow
中的原始对象(仍然与预期一样),但同时还将PERSONAL对象中"anInnerObject"
的值更改为布尔 true
:
it also changes the original object in $scope.fieldsToShow
(still as expected), BUT it ALSO changes the value of "anInnerObject"
in the PERSONAL object to the boolean true
:
$scope.fieldsToShow = [
{
"fields": {
"anInnerObject": {
"val": true // This changed, which I understand
}
},
"type": "LOGGED_IN"
},
{
"fields": {
"anInnerObject": true // BUT WHY this value also change? And why did it become true?
},
"type": "PERSONAL",
"user": 2,
"name": "Rick Astley"
}
];
这在世界上怎么可能发生?我一直把头撞在墙上好几个小时,尝试了一百万件事情,并向同事寻求帮助,但我根本找不到为什么这样做会如此?
How in the world can this happen?! I've been banging my head against the wall for hours, tried a million things and asked a colleague for help, but I simply can't find why this behaves like it does?
有人知道这怎么可能吗?欢迎所有提示!
Does anybody know how this can happen? All tips are welcome!
推荐答案
您需要了解中的
相同对象.两者都只是引用相同的存储位置.这就是在Javasript中对非原始类型的引用的工作方式. $ scope.currentObject
和原始对象$ scope.fieldsToShow
You need to understand that both both $scope.currentObject
and the original object in $scope.fieldsToShow
the same object. Both are just references to the same memory location. This is how references to non-primitive types work in Javasript.
如果您想拥有真正独立的不同对象,则需要在使用之前将其克隆:
If you want to have truly separate different object you need to clone it before using:
var $scope.currentObject = angular.copy($scope.fieldsToShow[1]);
这篇关于角度怪异:一个对象属性如何更改两个不同对象上的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!