角度怪异:一个对象属性如何更改两个不同对象的属性? [英] 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];
然后我再次单击复选框.正如预期的那样,这还将 "a": true
添加到 $scope.fieldsToShow
列表中第一个对象的 fields 对象.到现在为止还挺好.
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!
推荐答案
你需要明白 $scope.currentObject
和 中的 original 对象$scope.fieldsToShow
相同 对象.两者都只是对同一内存位置的引用.这就是 Javasript 中对非原始类型的引用的工作方式.
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屋!