通过重新使用先前设置的对象(Angular / Typescript),我开始努力分配2个暗对象数组。我的结果表明,最后一个分配优先于前两个分配,我无法弄清原因。你能看看我想念的东西吗?
export interface Criteria {
fieldValue: any;
fieldName: string;
childItems?: Criteria[];
}
// function to build my array of objects:
setCriteria() {
// parent object 1
// to be reused / reassigned to array below
const criteriaLevel1: Criteria = {
fieldName: 'Criteria name',
fieldValue: 'Crit-Level-1',
childItems: []
};
// parent object 2 - child of object 1
// to be reused / reassigned to array below
// into - childItems[0]
const criteriaLevel2: Criteria = {
fieldName: 'Criteria name',
fieldValue: 'Crit-Level-2',
childItems: []
};
// list of 3 different items to be assigned to array
// into - childItems[0].childItems[0] of each array record.
const itemsABC: string[] = [
'item AAA',
'item BBB',
'item CCC'
];
const criteriaArray = [];
let ix = 0;
itemsABC.forEach(item => {
console.log('item: ' + item);
criteriaArray[ix] = [];
criteriaArray[ix][0] = criteriaLevel1;
criteriaArray[ix][0].childItems[0] = criteriaLevel2;
criteriaArray[ix][0].childItems[0].childItems[0] = {
fieldName: 'name',
fieldValue: item + '-' + ix
};
ix++;
});
// output test
for (let i = 0; i < 3; i++) {
console.log('ix: ' + i);
for (const itemA of criteriaArray[i]) {
console.log('a: ' + itemA.fieldName + ' - ' + itemA.fieldValue);
for (const itemB of itemA.childItems) {
console.log('b: ' + itemB.fieldName + ' - ' + itemB.fieldValue);
for (const itemC of itemB.childItems) {
console.log('c: ' + itemC.fieldName + ' - ' + itemC.fieldValue);
}
}
}
}
}
我得到以下输出:
索引:0-插入项目:AAA项目
索引:1-插入项目:项目BBB
索引:2-插入项目:项目CCC
ix:0
a:标准名称-等级1
b:标准名称-等级2
c:名称-项目CCC-2 //但我希望在这里:项目AAA-0
ix:1
a:标准名称-等级1
b:标准名称-等级2
c:名称-项目CCC-2 //但我希望在这里:项目BBB-1
ix:2
a:标准名称-等级1
b:标准名称-等级2
c:名称-项目CCC-2 //在此处按预期进行操作:项目CCC-2
我在做什么错了?
答案 0 :(得分:1)
您正在为对象分配引用,因此criteriaArray
的所有三个元素都指向criteriaLevel1
和criteriaLevel2
的相同实例。
您可以选择几种方式来保持相同的模式:
criteriaArray[ix][0] = {...criteriaLevel1, childItems: []};
criteriaArray[ix][0].childItems[0] = {...criteriaLevel2, childItems: []};
const criteriaLevel1 = {
fieldName: 'Criteria name',
fieldValue: 'Crit-Level-1',
childItems: []
};
const criteriaLevel2 = {
fieldName: 'Criteria name',
fieldValue: 'Crit-Level-2',
childItems: []
};
const itemsABC = [
'item AAA',
'item BBB',
'item CCC'
];
const criteriaArray = [];
let ix = 0;
itemsABC.forEach(item => {
console.log('item: ' + item);
criteriaArray[ix] = [];
criteriaArray[ix][0] = {...criteriaLevel1, childItems: []};
criteriaArray[ix][0].childItems[0] = {...criteriaLevel2, childItems: []};
criteriaArray[ix][0].childItems[0].childItems[0] = {
fieldName: 'name',
fieldValue: item + '-' + ix
};
ix++;
});
for (let i = 0; i < 3; i++) {
console.log('ix: ' + i);
for (const itemA of criteriaArray[i]) {
console.log('a: ' + itemA.fieldName + ' - ' + itemA.fieldValue);
for (const itemB of itemA.childItems) {
console.log('b: ' + itemB.fieldName + ' - ' + itemB.fieldValue);
for (const itemC of itemB.childItems) {
console.log('c: ' + itemC.fieldName + ' - ' + itemC.fieldValue);
}
}
}
}
Object.assign()
criteriaArray[ix][0] = Object.assign({}, criteriaLevel1, {childItems: []});
criteriaArray[ix][0].childItems[0] = Object.assign({}, criteriaLevel2, {childItems: []});
const criteriaLevel1 = {
fieldName: 'Criteria name',
fieldValue: 'Crit-Level-1',
childItems: []
};
const criteriaLevel2 = {
fieldName: 'Criteria name',
fieldValue: 'Crit-Level-2',
childItems: []
};
const itemsABC = [
'item AAA',
'item BBB',
'item CCC'
];
const criteriaArray = [];
let ix = 0;
itemsABC.forEach(item => {
console.log('item: ' + item);
criteriaArray[ix] = [];
criteriaArray[ix][0] = Object.assign({}, criteriaLevel1, {childItems: []});
criteriaArray[ix][0].childItems[0] = Object.assign({}, criteriaLevel2, {childItems: []});
criteriaArray[ix][0].childItems[0].childItems[0] = {
fieldName: 'name',
fieldValue: item + '-' + ix
};
ix++;
});
for (let i = 0; i < 3; i++) {
console.log('ix: ' + i);
for (const itemA of criteriaArray[i]) {
console.log('a: ' + itemA.fieldName + ' - ' + itemA.fieldValue);
for (const itemB of itemA.childItems) {
console.log('b: ' + itemB.fieldName + ' - ' + itemB.fieldValue);
for (const itemC of itemB.childItems) {
console.log('c: ' + itemC.fieldName + ' - ' + itemC.fieldValue);
}
}
}
}
请注意,这两种方法都执行浅表复制,因此您必须手动考虑嵌套对象的引用。
另一种方法是创建一个辅助函数来实例化一个新对象。
function generateCriteria(fieldName, fieldValue) {
return () => ({
fieldName: fieldName,
fieldValue: fieldValue,
childItems: []
});
}
const criteriaLevel1 = generateCriteria('Criteria name', 'Crit-Level-1');
const criteriaLevel2 = generateCriteria('Criteria name', 'Crit-Level-2');
const itemsABC = [
'item AAA',
'item BBB',
'item CCC'
];
const criteriaArray = [];
let ix = 0;
itemsABC.forEach(item => {
console.log('item: ' + item);
criteriaArray[ix] = [];
criteriaArray[ix][0] = criteriaLevel1();
criteriaArray[ix][0].childItems[0] = criteriaLevel2();
criteriaArray[ix][0].childItems[0].childItems[0] = {
fieldName: 'name',
fieldValue: item + '-' + ix
};
ix++;
});
for (let i = 0; i < 3; i++) {
console.log('ix: ' + i);
for (const itemA of criteriaArray[i]) {
console.log('a: ' + itemA.fieldName + ' - ' + itemA.fieldValue);
for (const itemB of itemA.childItems) {
console.log('b: ' + itemB.fieldName + ' - ' + itemB.fieldValue);
for (const itemC of itemB.childItems) {
console.log('c: ' + itemC.fieldName + ' - ' + itemC.fieldValue);
}
}
}
}
答案 1 :(得分:0)
按值划分对象和按引用划分对象是一件棘手的事情。在第一次迭代中分配criterialLevel1时,在下一次迭代中,实际上实际上一直都在更新criteriaLeve1变量的引用。
criteriaArray[ix] = [];
criteriaArray[ix][0] = {...criteriaLevel1, childItems: []}; // creating a new object and spreading it, Note the child Items created new else as it is an array would have been passed by reference as well.
criteriaArray[ix][0].childItems[0] = {...criteriaLevel2, childItems: []};
criteriaArray[ix][0].childItems[0].childItems[0] = {
fieldName: 'name',
fieldValue: item + '-' + ix
};
我建议您定义这些变量,为什么不直接分配它们,而您可以在一行中完成:
criteriaArray[ix] = [{
fieldName: 'Criteria name',
fieldValue: 'Crit-Level-1',
childItems: [{
fieldName: 'Criteria name',
fieldValue: 'Crit-Level-2',
childItems: [{
fieldName: 'name',
fieldValue: item + '-' + ix
}]
}]
}];