在我的Angular应用程序的一个组件中,我订阅了一个Observable,它从我的一个服务中的函数返回一个json数组 . 该响应正确地返回到组件 .
在.subscribe中,我使用嵌套for循环将每个JSON对象的字段映射到新类实例(对象)的属性,然后将每个实例/对象添加/推送到该类类型的数组中 .
当我在控制台中查看来自console.log(this.contractsList)的控制台中的结果时,所有字段都会正确填充,但显示为:
listOffices:数组(0)
此字符串数组应始终具有1或2个元素 .
我意识到我应该在我的服务中而不是组件中执行这种反序列化/映射但是我不认为这导致了这个问题 . 一旦我开始工作,我计划进行重构 . 相反,我认为它与Closure有关,但仍然让我感到困惑 . 我假设是因为当我在尝试将其值分配给对象之前的任何时候尝试console.log(officeval)时,我在控制台中看到了正确的值 .
这是我的组件中调用subscribe的方法:
getContracts() {
this.contractService.getContracts().subscribe(
(res) => {
let officeval = new Array<string>();
for (var x = 0; x < res.length; x++) {
for (var z = 0; z < res[x].length; z++) {
if (res[x][z].resources.office !== undefined){
for (var a = 0; a < res[x][z].resources.office.values.length; a++) {
officeval.push(res[x][z].resources.office.values[a]);
}
}
else {
officeval.push("Not a Hive Policy");
}
this.createContract(res[x][z].id, res[x][z].name,"placeholder for type",res[x][z].isEnabled, res[x][z].service,
officeval, ["q", "w"], ["q", "w"],["q", "w"], ["q", "w"],["q","r"]);
} console.log(this.contractsList);
}
},
(err) => console.log(err))
console.log("logging contracts");
}
createContract(id:number, contractName:string, type:string, isEnabled:boolean,
service:string, listOffices:string[], listRooms:string[],
listSeats:string[], contractItemsEntries:string[], contractItemsOwners:string[], contractItemsSessions:string[]) {
this.contractsList.push (new Contract (id, contractName, type, isEnabled,
service, listOffices, listRooms,
listSeats, contractItemsEntries, contractItemsOwners, contractItemsSessions ));
}
}
以下是Chrome控制台中输出的示例:
[Contract, Contract, Contract...] x6
-opened Contract Array:
0:Contact
1:Contract
2:Contract
...
-opened Contract:
listOffices: Array(0) -- ???
listRooms: Array(2) --contain correct values
listSeats: Array(2) --contain correct values
id:1
isEnabled: true
service: contractService
type: "placeholder for type"
3 回答
既然我们对你的res对象没有任何线索,你确定吗
res[x][z].resources.office.values.length > 0
这是您的officeVal未填充的唯一情况 . (因为它不明显循环)
所以我敢打赌 .
从查看代码开始,
office.values
的长度必须为0,这意味着没有添加任何内容,因此是一个数组(0) . 如果您可以发布从getContracts返回的JSON,则可以确认这一点 .此外,一旦你将它放入officeval数组,你可能会注意到它有更多的项目,因为它不会出现你在循环的每次迭代中清除officeval . 这可能是有意的,但我的猜测是,它不是 .
该问题的根本原因与:
没有意识到javascript通过引用传递复杂数据类型(参见this article)(这些帖子是我如何通过值而不是引用来完成传递的指南:one,two)
在每次内部for循环迭代后,不将officeval数组重置为0
要解决,我:
将officeval数组的声明移到我的外部函数之外,以便可以使用this关键字在我的内部函数中引用它
使用slice方法创建officeval的by值副本,然后将其传递给我的内部函数,用于创建新 Contract 并将它们添加到contractsList数组中 .
每次将新 Contract 推送到contractsList后立即重置officeval的值 .
这是我的代码的最终版本: