我有一个组件,它在订阅的页面上显示一些数据。
我正在尝试clone
该变量并对其进行更改,而不会影响用于呈现页面视图的原始数据。
import { UtilsService } from '../shared';
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'app-review',
templateUrl: './review.component.html',
styleUrls: ['./review.component.css']
})
export class ReviewComponent implements OnInit {
@Input() payload: any = null;
// Object of strings that are used for the details
langStr: any = {
noDepartment: 'No Department Change',
noSegment: 'No Segment Change',
noMarket: 'No Budget Market Change',
noIncentive: 'No Incentive Plan Change',
noRole: 'No Role Change',
noProductionDate: 'No Production Date Change',
noLanguage: 'No Language Change',
noShift: 'No Shift Change',
noSupervisor: 'No Supervisor Change'
};
// Used to scan through the final payload and assign default values if missing
optionalFields = ['budgetMarket',
'hierarchy',
'incentivePlan',
'primaryLanguage',
'secondaryLanguage',
'role',
'segment',
'shiftID',
'supervisor'];
modifiedData: any;
constructor(
private utils: UtilsService
) {
}
ngOnInit() { }
submitChanges() {
this.modifiedData = this.payload;
// Loop over all of the keys in our formData object
for (const key in this.modifiedData.formData) {
// Find shift by property if the key exists within our defined array
if (this.modifiedData.formData.hasOwnProperty(key) && this.utils.isInArray(this.optionalFields, key)) {
// If our object data doesnt have a value, set it to -1
if (!this.modifiedData.formData[key].length) {
this.modifiedData.formData[key] = '-1';
}
}
}
// Send to database
console.log(this.modifiedData)
}
}
在上述情况下,我尝试将this.payload
的订阅数据设置为名为modifiedData
的新变量。然后我修改了该任务中的一些数据。
但是,只要我调用函数submitChanges()
,我的HTML视图就会获得对modifiedData
所做更改的更新,即使它没有订阅它。
我认为这与this.modifiedData = this.payload;
以某种方式更新原始数据(payload
)有关。
有没有办法在payload
不被触及的情况下执行此操作。我基本上只是克隆它并在将其提交给我的数据库调用之前进行一些更改。
答案 0 :(得分:8)
您没有克隆该对象。您只是将对该对象的引用分配给另一个变量。他们都指向完全相同的对象。
如果你想实际克隆你的对象,你基本上有两个选择:
首先,简单,有点hacky并且要小心使用,因为不会涵盖所有内容:
this.modifiedData = JSON.parse(JSON.stringify(this.payload));
会给你一个基本克隆的新对象。
如果你想拥有更强大的克隆,你必须通过遍历你的对象并从头开始创建一个新的手动来手动完成(或者使用像lodash这样的库,它有方法)。
更新只是为了完成:其他答案建议this.modifiedData Object.assign({}, this.payload)
和this.modifiedData = {...this.payload};
这对于简单而非嵌套对象很好,因为它们都是shallow copy
而不是deep copy
你的宾语。
由于JSON.parse(JSON.stringify(obj)
将忽略除了对象,数组,数字和字符串以及布尔值之外的所有内容,因此最好的选择仍然是手动克隆(或使用像lodash一样的库)。
答案 1 :(得分:2)
使用类似的东西:
// Clone the object to retain a copy
this.originalProduct = Object.assign({}, value);
或者在你的情况下:
this.modifiedData = Object.assign({}, this.payload);
这会将this.payload
中所有属性的值复制到新对象中。
此处的文档位于:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign并且包括对深度克隆的讨论"的问题。
否则,此代码:
this.modifiedData = this.payload;
正在分配参考。因此,对原始文件的任何更改都会更改" copy"同样。