我在对象(TypeScript,Angular4,Ionic3)上进行深度复制/克隆时遇到问题,该对象还包含其他对象的列表。每当我更改副本中的子对象时,原始对象也会受到更改的影响,反之亦然。我的REST API为我提供了以下JSON:
我有2种类型的对象在这种情况下是相关的,有更多,但它们不需要更改,因此我不包括那些:
import { Declaration } from './declaration.entity';
export class Period{
constructor(
public number: number,
public status: string,
public year: number,
public month: number,
public sum: number,
public orderNumber: string,
public userId: string,
public submitDate: Date,
public comment: string,
public declarations: Declaration[]
){}
}
和
import { FileCustom } from './file.entity';
import { Period } from './period.entity';
export class Declaration{
constructor(
public id: number,
public status: string,
public name: string,
public description: string,
public amount: number,
public date: Date,
public period: Period,
public userId: string,
public files: FileCustom[],
public comment: string
){}
}
我想更改句点内的声明字段。我有一个名为期间(期间列表)的对象,我想克隆它。我需要时间不受影响。我看了一些其他主题和可能的解决方案并尝试了它们:
let cloned = this.periods.map(x => Object.assign({},x));
和
let cloned = this.periods.map(x => Object.assign([],x));
从这个主题:
Deep copy an array in Angular 2 + TypeScript
当我使用上述解决方案之一并更改副本中期间的注释字段时,原始文件保持不变。但是当我更改句点内的声明的注释字段时,原始文件也会更改,这是我想要阻止的。如何在没有任何孩子任何引用原件的情况下深度复制/克隆我的句点列表?
提前致谢。
答案 0 :(得分:0)
如果对象原型不是问题且对象不包含函数,您可以JSON.stringify()
并将其解析回新对象
let cloned = this.periods.map(x => JSON.parse(JSON.stringify(x)));
或者一次串联整个this.periods
let cloned = JSON.parse(JSON.stringify(this.periods))
答案 1 :(得分:0)
您可以使用lodash的cloneDeep
函数来执行此操作,以避免来回对象进行字符串化。
对于您的Angular项目,您可以这样做:
使用lodash
或yarn add lodash
npm install lodash
由于我们将仅使用cloneDeep
函数,为了减少包,我们只将函数导入组件,而不是整个lodash
库:
import * as cloneDeep from 'lodash/cloneDeep';
我们将像这样使用它来深度复制对象:
copiedList = cloneDeep(originalList);
现在将某些内容更改为嵌套在副本中的对象不会更改原始对象。
此解决方案将为您的生产Angular捆绑添加18 kb。