角度怪异:一个对象属性如何在两个不同的对象上更改属性?

时间:2015-11-17 08:31:34

标签: javascript angularjs checkbox reference angular-ngmodel

我正在使用Angularjs建立一个网站,其中我有一个对象列表:

$scope.fieldsToShow = [
    {
        "fields": {},
        "type": "LOGGED_IN"
    },
    {
        "fields": {},
        "type": "PERSONAL",
        "user": 2,
        "name": "Rick Astley"
    }
];
然后我将其中一个对象选择为变量:

var $scope.currentObject = $scope.fieldsToShow[1];

让用户使用一些复选框更改它:

<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更改为数组中的第一个对象:

$scope.currentObject = $scope.fieldsToShow[0];

然后再次点击该复选框。正如预期的那样,这也会将"a": true添加到$scope.fieldsToShow列表中第一个对象的fields对象。到现在为止还挺好。

我现在想在fields对象中添加一个对象。所以我创建了另一个复选框:

<input ng-model="currentObject.fields.anInnerObject.val" type="checkbox">

然后我再次更改为PERSONAL对象($scope.currentObject = $scope.fieldsToShow[1];)并单击复选框。正如预期的那样,这会改变$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

{
    "fields": {
        "anInnerObject": {
            "val": true
        }
    },
    "type": "LOGGED_IN",
}

它还会更改$scope.fieldsToShow中的原始对象(仍然如预期的那样),但它也会将PERSONAL对象中"anInnerObject"的值更改为布尔值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"
    }
];

世界怎么会发生这种情况?!我已经把头撞到了墙上好几个小时,尝试了一百万件事并向同事寻求帮助,但我根本无法找到为什么会这样做呢?

有人知道这会怎么样吗?欢迎所有提示!

1 个答案:

答案 0 :(得分:1)

您需要了解$scope.currentObject 相同对象中的$scope.fieldsToShow原始对象。两者都只是对相同内存位置的引用。这就是对非原始类型的引用在Javasript中的工作方式。

如果你想拥有真正独立的不同的对象,你需要在使用之前克隆它:

var $scope.currentObject = angular.copy($scope.fieldsToShow[1]);