AngularJS 有 angular.copy()
来实现对象和数组的深度拷贝。
Angular 中是否也有类似的方法呢?
AngularJS 有 angular.copy()
来实现对象和数组的深度拷贝。
Angular 中是否也有类似的方法呢?
你也可以使用:
JSON.parse(JSON.stringify(Object))
如果它在你的范围内,它将存在于每个Angular组件、指令等中,也存在于每个节点环境中。
除非你有循环引用,否则它应该可以工作,并且将有效地使你的变量引用与原始对象分离。
Object.assing({}, oldObject, JSON.parse(JSON.stringify(oldObject)))
,这将从你的对象文字重新填充函数属性,并使用JSON创建一个与原始对象没有任何关系的深层副本。 - Gabriel Balsa Cantú另一个选项是实现您自己的功能:
/**
* Returns a deep copy of the object
*/
public static deepCopy(oldObj: any) {
var newObj = oldObj;
if (oldObj && typeof oldObj === "object") {
if (oldObj instanceof Date) {
return new Date(oldObj.getTime());
}
newObj = Object.prototype.toString.call(oldObj) === "[object Array]" ? [] : {};
for (var i in oldObj) {
newObj[i] = this.deepCopy(oldObj[i]);
}
}
return newObj;
}
这个问题不是如何在Angular 2中使用angular.copy的副本,因为提问者询问深拷贝对象的方法。链接的答案推荐使用Object.assign(),但它并不会做深拷贝。
实际上,使用Angular2并不限制您使用其他库,例如jQuery的$.clone()函数或lodash的_.cloneDeep()来进行对象的深拷贝。
大多数常用库都可以通过typings CLI工具获得其类型定义文件,因此即使从TypeScript进行转换,您也可以无缝地使用任何您想要的内容。
您可以使用lodash的cloneDeep方法在Angular中进行对象的深度复制:
通过yarn add lodash
或npm install lodash
安装lodash。
在您的组件中,导入cloneDeep
并使用它:
import * as cloneDeep from 'lodash/cloneDeep';
...
clonedObject = cloneDeep(originalObject);
仅增加了18kb到您的构建中,这些好处是非常值得的。
如果您需要更深入地了解为什么要使用lodash的cloneDeep方法,我也在这里写了一篇文章。
Create helper class with name deepCopy.ts
/*
* DeepCopy class helps to copy an Original Array or an Object without impacting on original data
*/
export class DeepCopy {
static copy(data: any) {
let node;
if (Array.isArray(data)) {
node = data.length > 0 ? data.slice(0) : [];
node.forEach((e, i) => {
if (
(typeof e === 'object' && e !== {}) ||
(Array.isArray(e) && e.length > 0)
) {
node[i] = DeepCopy.copy(e);
}
});
} else if (data && typeof data === 'object') {
node = data instanceof Date ? data : Object.assign({}, data);
Object.keys(node).forEach((key) => {
if (
(typeof node[key] === 'object' && node[key] !== {}) ||
(Array.isArray(node[key]) && node[key].length > 0)
) {
node[key] = DeepCopy.copy(node[key]);
}
});
} else {
node = data;
}
return node;
}
}
无论何时需要,请导入deepCopy文件并按如下代码使用DeepCopy.copy(arg);,这里的arg可以是您想要的对象或数组。
e!=={}
总是为真,而且由于 typeof [] === 'object'
,OR-pipes 后面的部分永远不会按预期工作。这也会简单地复制遇到的任何日期。那个三元运算符的第一部分最好看起来像 ? new Date(data) :
。 - Sjeiti对于KrishnamrajuK的答案进行一些修改
export class DeepCopy {
static copy(data: any, objMap?: WeakMap<any, any>) {
if (!objMap) {
// Map for handle recursive objects
objMap = new WeakMap();
}
// recursion wrapper
const deeper = value => {
if (value && typeof value === 'object') {
return DeepCopy.copy(value, objMap);
}
return value;
};
// Array value
if (Array.isArray(data)) return data.map(deeper);
// Object value
if (data && typeof data === 'object') {
// Same object seen earlier
if (objMap.has(data)) return objMap.get(data);
// Date object
if (data instanceof Date) {
const result = new Date(data.valueOf());
objMap.set(data, result);
return result;
}
// Use original prototype
const node = Object.create(Object.getPrototypeOf(data));
// Save object to map before recursion
objMap.set(data, node);
for (const [key, value] of Object.entries(data)) {
node[key] = deeper(value);
}
return node;
}
// Scalar value
return data;
}
}
let cloned = source.map(x => Object.assign({}, x));
或者
let cloned = source.map((x) => {
return { ...x };
});
这里的一些答案依赖于lodash
,在导入angular 10+时可能会出现警告消息,例如:
WARNING in xxxxx.ts depends on lodash/cloneDeep. CommonJS or AMD dependencies can cause optimization bailouts.
clone
:一个具有有限依赖关系的轻量级克隆实用程序。clone
,您只需要安装这两个软件包:npm install clone
npm install --save-dev @types/clone
创建一个服务(服务不是必需的,但我更喜欢这种方法),该服务使用克隆API:
import { Injectable } from '@angular/core';
import * as clone from 'clone';
@Injectable()
export class ObjectCloneService {
public cloneObject<T>(value: T): T {
return clone<T>(value);
}
}
记得将服务添加到你的模块中。
如果您想使用cloneDeep而不需要任何“CommonJS或AMD依赖项可能会导致优化失败”,您可以像这样使用它:
npm i lodash-es --save
然后在任何组件中都可以简单地使用:
import { cloneDeep } from 'lodash-es';
// ...
let a = cloneDeep(b);
copyFactory = (() ->
resource = ->
resource.__super__.constructor.apply this, arguments
return
this.extendTo resource
resource
).call(factory)
angular.copy()
一样。 - Ankit Singhangular.copy()
啊。我应该删除这个问题吗? - Ankit Singh