问题
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">
which changes both $scope.currentObject
:
{
"fields": {
"a": true
},
"type": "PERSONAL",
"user": 2,
"name": "Rick Astley"
}
and the original object in $scope.fieldsToShow
:
$scope.fieldsToShow = [
{
"fields": {},
"type": "LOGGED_IN"
},
{
"fields": {
"a": true
},
"type": "PERSONAL",
"user": 2,
"name": "Rick Astley"
}
];
I then change the $scope.currentObject
to the first object in the array:
$scope.currentObject = $scope.fieldsToShow[0];
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.
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">
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"
}
and the original object in $scope.fieldsToShow
:
$scope.fieldsToShow = [
{
"fields": {},
"type": "LOGGED_IN"
},
{
"fields": {
"anInnerObject": {
"val": true
}
},
"type": "PERSONAL",
"user": 2,
"name": "Rick Astley"
}
];
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",
}
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!
回答1:
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]);
来源:https://stackoverflow.com/questions/33752295/angular-weirdness-how-can-one-object-attribute-change-an-attribute-on-two-diffe