22

我想扩展一些递归属性(又名深拷贝)。就像 jQuery 一样。我不包括 jquery 仅 b/c 的一件事。

jQuery.extend( true, target, object1 )

你知道有什么优雅的方式可以用简单的 javascript 或 angularjs 来实现吗?

更新 请看一下并尝试完成相同的结果 http://plnkr.co/edit/GHabYbyhsqtfBPtplksO?p=preview

我确实查看了 .copy() 但“属性(用于对象)被删除”

4

6 回答 6

28

这是一个基于 angular.extend 函数的 extendDeep 函数。如果你把它添加到你的 $scope 中,你就可以调用

$scope.meta = $scope.extendDeep(ajaxResponse1.myMeta, ajaxResponse2.defaultMeta);

并获得您正在寻找的答案。

$scope.extendDeep = function extendDeep(dst) {
  angular.forEach(arguments, function(obj) {
    if (obj !== dst) {
      angular.forEach(obj, function(value, key) {
        if (dst[key] && dst[key].constructor && dst[key].constructor === Object) {
          extendDeep(dst[key], value);
        } else {
          dst[key] = value;
        }     
      });   
    }
  });
  return dst;
};

注意:此函数具有将值从后面的参数复制到前面的参数的副作用。对于此副作用的简单修复,您可以更改dst[key] = valuedst[key] = angular.copy(value).

于 2013-03-09T14:34:24.203 回答
17

这里的所有答案都对Angular 1.4 之前的版本有效

从 Angular 1.4 开始,您可以使用它angular.merge来做到这一点:

与 extend() 不同,merge()递归地下降到源对象的对象属性中,执行深度复制

https://docs.angularjs.org/api/ng/function/angular.merge

于 2015-03-19T14:53:15.653 回答
7
function deepExtend(destination, source) {
  for (var property in source) {
    if (source[property] && source[property].constructor &&
     source[property].constructor === Object) {
      destination[property] = destination[property] || {};
      arguments.callee(destination[property], source[property]);
    } else {
      destination[property] = source[property];
    }
  }
  return destination;
}

普朗克

来源:https ://gist.github.com/gregdangelo/2343158

于 2013-03-09T14:29:36.207 回答
1

基于 Ryan 的代码,您可以缩短对象检查,并且您也不应该扩展函数,这样您就不会覆盖对象指针。

var extendDeep = function extendDeep(dst) {
    angular.forEach(arguments, function(obj) {
        if (obj !== dst) {
            angular.forEach(obj, function(value, key) {
                if (dst[key] && angular.isObject(dst[key])) {
                    extendDeep(dst[key], value);
                } else if(!angular.isFunction(dst[key])) {
                    dst[key] = value;
                }
            });
        }
    });
    return dst;
};
于 2014-11-10T15:47:16.457 回答
0

与 Ryan 相同的解决方案,但支持数组合并

function extendDeep(dst) {
      angular.forEach(arguments, function (obj) {
          if (obj !== dst) {
            angular.forEach(obj, function (value, key) {
                if (dst[key] && dst[key].constructor && dst[key].constructor === Object) {
                  extendDeep(dst[key], value);
                } else if (dst[key] && dst[key].constructor && dst[key].constructor === Array) {
                  dst[key].concat(value);
                } else if(!angular.isFunction(dst[key])) {
                  dst[key] = value;
                }
              }
            );
          }
        }
      );
      return dst;
    }
于 2014-12-31T09:33:36.957 回答
-1

Angular 有一个复制方法:

角复制

于 2013-03-09T13:05:39.817 回答