在组件ts executeCommand方法中,我正在克隆这样一个已经存在的对象
let newCommandArray = new Object();
newCommandArray = this.commandArray[commandId];
之后,我遍历newCommandArray
并对数据进行一些操作。当我操纵克隆对象newCommandArray上的数据时,原始对象数据this.commandArray[commandId]
也发生了变化,这使得模板无法呈现视图。在item.ParamProps.options
中输入错误,
Error trying to diff '"[{\"name\":\"option1\",\"value\":\"option1\"},{\"name\":\"option2\",\"value\":\"option2\"}]"'. Only arrays and iterables are allowed
是<md2-option *ngFor="let option of item.ParamProps.options">
我们将帮助您克服这一问题。
HTML模板:
<div *ngSwitchCase="'select'">
<div class="form-group" *ngIf="item.ParamProps.visible">
<label>{{item.ParamName}}</label><br>
<div class="wrapper">
<md2-select [(ngModel)]="item.ParamValue"
[name]="item.ParamID">
<md2-option *ngFor="let option of item.ParamProps.options"
[value]="option.value">{{option.name}}
</md2-option>
</md2-select>
<i class="bar"></i>
</div>
</div>
</div>
组件TS:
export class DynamicCommandComponent implements OnInit {
public commands: ICommandList;
public message: string;
public commandArray: any;
public commandHistoryList: any;
public filterTerm: string;
private itemId: any;
@ViewChild('commandHistoryModal') commandHistoryModal: any;
constructor(private commandService: DynamicCommandService, private globalDataService: GlobalDataService) {
this.commands = null;
this.commandArray = {};
this.commandHistoryList = {};
this.filterTerm = '';
}
public ngOnInit() {
this.itemId = Number(this.globalDataService.getAgentID());
this.commandService.getCommandsSet(this.itemId).subscribe((res: ICommandList) => {
this.commands = res;
this.storeCommands(res);
this.loadAllCommandStatus(this.itemId);
});
}
public executeCommand(commandId: number) {
this.commandService.getUserFeatures().subscribe((res: any) => {
this.commandArray[commandId].userID = res.userId;
let itemIdArray = new Array<number>();
itemIdArray.push(this.itemId);
this.commandArray[commandId].ItemIDs = itemIdArray;
this.commandArray[commandId].name = UUID.UUID();
let newCommandArray = new Object();
newCommandArray = this.commandArray[commandId];
newCommandArray.CommandParamList[0].ParamProps.options = JSON.stringify(newCommandArray.CommandParamList[0].ParamProps.options);
newCommandArray.CommandParamList.forEach(element => {
element.ParamProps.options = JSON.stringify(element.ParamProps.options);
});
console.log(newCommandArray); // Output => [{\"name\":\"option1\",\"value\":\"option1\"},{\"name\":\"option2\",\"value\":\"option2\"}]"
console.log(this.commandArray[commandId]); // Output => "[{\"name\":\"option1\",\"value\":\"option1\"},{\"name\":\"option2\",\"value\":\"option2\"}]"
this.commandService.executeCommand(newCommandArray).subscribe();
});
}
}
答案 0 :(得分:2)
您的代码有一些问题。
首先,在这些行中:
let newCommandArray = new Object();
newCommandArray = this.commandArray[commandId];
您实际上并没有克隆对象。首先将newCommandArray
设置为一个空对象{}
,但随后您继续说'实际上,算了。 NewCommandArray将指向this.commandArray[commandId]
。这就是为什么更改一个更改另一个更改的原因–两个变量名称都指向同一对象。
如果要实际克隆对象,则有无数种方法,每种方法都有优点和缺点,这取决于要克隆的对象的复杂性。有两种方法可以做到:
const newCommandArray = { ...this.commandArray[commandId] };
或
const newCommandArray = JSON.parse(JSON.stringify(this.commandArray[commandID]));
通过我使用const的方式,因为一旦分配了该对象,就不想将变量重新分配给另一个对象。您可以愉快地添加或更改其属性,而不会导致与使用const有关的任何错误。
然后,在两个地方无缘无故地对事物进行字符串化
newCommandArray.CommandParamList[0].ParamProps.options = JSON.stringify(newCommandArray.CommandParamList[0].ParamProps.options);
...
newCommandArray.CommandParamList.forEach(element => {
element.ParamProps.options = JSON.stringify(element.ParamProps.options);
});
您为什么要对这些选项进行分类?无论如何,这就是为什么您遇到另一个问题,即ngFor感到困惑的原因。它想循环遍历一个数组,如果您没有将其转换为字符串的话,该数组就可以了!
如果您想了解有关克隆对象的更多信息,请看这里:
What is the most efficient way to deep clone an object in JavaScript?