AngularJS - 将一个对象的常见属性复制到另一个对象

8
我有一个这样的控制器:
CheckoutController = function() {
    $scope.Profile = {
        firstname : 'Ruchir',
        middlename : 'Shakun',
        lastname : 'Gupta',
        email : 'ruchir@example.com',
        cellphone : '9876543210'
    }

    $scope.BillingDetails = {
        firstname : undefined,
        middlename : undefined,
        lastname : undefined,
        addressline : undefined,
        city : undefined,
        zipcode : undefined
    }

    $scope.update = function() {
        // I want to write some awesome code here as explained below
    }
}

现在,在$scope.update函数中,我想写一些仅复制“公共属性”的内容,即firstnamemiddlenamelastname$scope.Profile$scope.BillingDetails
我尝试了angular.copyangular.extend,但是:
- angular.extend合并了$scope.BillingDetails$scope.Profile。所以我也得到了$scope.BillingDetails中的emailcellphone属性,这不是我想要的。 - angular.copy覆盖了$scope.BillingDetails,我失去了$scope.BillingDetails中的addresslinecityzipcode,这也不是我想要的。
我希望我的update函数能够使$scope.BillingDetails等于下面的对象:
{
    firstname : 'Ruchir',
    middlename : 'Shakun',
    lastname : 'Gupta',
    addressline : undefined,
    city : undefined,
    zipcode : undefined    
}

这个场景只是一个例子。为了缩短我的问题长度,我只提到了5-6个属性。实际上,我需要处理的属性超过20个,而且所有属性都是动态的。因此,通过从“Profile”复制每个属性firstnamemiddlenamelastnameBillingDetails中,这种方法对我不起作用。我该怎么办?

$scope.BillingDetails.firstname = $scope.Profile.firstname 这个怎么样? - kelsier
你可以创建一个包含所需属性并设置值的额外的json对象。这样你就可以将$scope.BillingDetails与该额外的json对象合并。可能不是最优解,但是很有帮助。 - Sven Schürmann
3个回答

14

你可以尝试类似以下的做法:

$scope.update = function() {
  _update($scope.Profile, $scope.BillingDetails);
}

function _update(srcObj, destObj) {
  for (var key in destObj) {
    if(destObj.hasOwnProperty(key) && srcObj.hasOwnProperty(key)) {
      destObj[key] = srcObj[key];
    }
  }
}

plunker


谢谢!在我看来,使用hasOwnProperty比@Tip-Sy提供的解决方案更好。 - Ruchir Gupta
1
谢谢 - 虽然他也很好心地在代码中提供了解释!;) 希望以上内容仍然相当自我解释。 - JcT
1
只是为了澄清,以便帮助某些人:对于现有属性的使用,无论是使用 myObj.hasOwnProperty('propertyName') 还是 'propertyName' in myObj 都可以工作,而不需要检查它们是否为 nullundefined 等;但是,使用 hasOwnProperty 将忽略对象的继承属性,而 in 则通常是您想要的。 - JcT

4

简单。只需像这样分配它们:

$scope.update = function() {
    $scope.BillingDetails.firstname = $scope.Profile.firstname;
    $scope.BillingDetails.middlename = $scope.Profile.middlename;
    $scope.BillingDetails.lastname = $scope.Profile.lastname;
}

我很难想出一种更直接简单的方法来从一个对象复制几个属性到另一个对象。
如果你需要复制超过3个属性,可以尝试以下代码:
$scope.update = function() {
    // Add the properties you want to copy to this array.
    var properties = ['firstname', 'middlename', 'lastname'];
    for(var i = 0; i < properties.length; i++){
         $scope.BillingDetails[properties[i]] = $scope.Profile[properties[i]];
    }
}

或者将数组作为参数传递:

$scope.update = function(properties) {
    for(var i = 0; i < properties.length; i++){
         $scope.BillingDetails[properties[i]] = $scope.Profile[properties[i]];
    }
}

$scope.update(['firstname', 'middlename', 'lastname']);

1
哦,你应该在问题中提到这一点。我会看看能否写出一些东西。 - Cerbrus
抱歉,我在StackOverflow上真的是个新手。因此,我将编辑问题。 - Ruchir Gupta
1
@RuchirGupta:看一下我最后的代码块,只是一个小调整。 - Cerbrus
2
@RuchirGupta:你应该提到的另一个细节是...在那种情况下,Tip-Sy的答案应该有效... - Cerbrus
2
@Cerbrus 你说得对,OP在他的问题中缺少许多细节。我试图猜测他真正想要什么,这就是我提出替代答案的方式。但是你的答案也值得点赞,给你! - Tip-Sy
显示剩余8条评论

3

实际上,您尝试使用Profile的值更新BillingDetails,对于它们共有的属性,是这样的吧?

如果您可以将BillingDetails的默认值更改为null而不是undefined,则可以尝试使用以下代码:

$scope.BillingDetails = {
    firstname : null,
    middlename : null,
    lastname : null,
    addressline : null,
    city : null,
    zipcode : null
}

$scope.update = function() {
    for(var key in $scope.Profile) {
        if(typeof $scope.BillingDetails[key] !== 'undefined') {
            $scope.BillingDetails[key] = $scope.Profile[key];
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接