首页 文章

Angular App(对象中的数组未填充实例化期间传递的值)

提问于
浏览
0

在我的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 回答

  • 0

    既然我们对你的res对象没有任何线索,你确定吗

    res[x][z].resources.office.values.length > 0

    这是您的officeVal未填充的唯一情况 . (因为它不明显循环)

    所以我敢打赌 .

  • 0

    从查看代码开始, office.values 的长度必须为0,这意味着没有添加任何内容,因此是一个数组(0) . 如果您可以发布从getContracts返回的JSON,则可以确认这一点 .

    此外,一旦你将它放入officeval数组,你可能会注意到它有更多的项目,因为它不会出现你在循环的每次迭代中清除officeval . 这可能是有意的,但我的猜测是,它不是 .

  • 0

    该问题的根本原因与:

    • 没有意识到javascript通过引用传递复杂数据类型(参见this article)(这些帖子是我如何通过值而不是引用来完成传递的指南:onetwo

    • 在每次内部for循环迭代后,不将officeval数组重置为0

    要解决,我:

    • 将officeval数组的声明移到我的外部函数之外,以便可以使用this关键字在我的内部函数中引用它

    • 使用slice方法创建officeval的by值副本,然后将其传递给我的内部函数,用于创建新 Contract 并将它们添加到contractsList数组中 .

    • 每次将新 Contract 推送到contractsList后立即重置officeval的值 .

    这是我的代码的最终版本:

    officeval: string[] = []
    
    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");
                     }
    
                var testArray = this.officeval.slice(0);
    
                this.createContract(res[x][z].id, res[x][z].name,"placeholder for type",res[x][z].isEnabled, res[x][z].service,
                testArray, ["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 ));
    
        this.offiveval.length = 0;
    
      }
    }
    

相关问题