Angular App(对象中的数组在实例化过程中未填充传递的值)

Angular App(对象中的数组在实例化过程中未填充传递的值),angular,typescript,closures,rxjs,observable,Angular,Typescript,Closures,Rxjs,Observable,在Angular应用程序的一个组件中,我订阅了一个Observable,它从我的一个服务中的函数返回一个json数组。该响应将正确返回到组件 在.subscribe中,我使用嵌套for循环将每个JSON对象的字段映射到新类实例(对象)的属性中,然后将每个实例/对象添加/推送到该类类型的数组中 当我从console.log(this.contractsList)在Chrome中查看控制台中的结果时,所有字段都被正确填充,只有一个字段显示为: 列表办公室:数组(0) 此字符串数组应始终具有1或2个元

在Angular应用程序的一个组件中,我订阅了一个Observable,它从我的一个服务中的函数返回一个json数组。该响应将正确返回到组件

在.subscribe中,我使用嵌套for循环将每个JSON对象的字段映射到新类实例(对象)的属性中,然后将每个实例/对象添加/推送到该类类型的数组中

当我从console.log(this.contractsList)在Chrome中查看控制台中的结果时,所有字段都被正确填充,只有一个字段显示为:

列表办公室:数组(0)

此字符串数组应始终具有1或2个元素

我意识到我可能应该在我的服务中而不是在组件中执行这种反序列化/映射,但是我认为这不会导致这个问题。我计划在工作后进行重构。相反,我认为这与结束有关,这仍然让我有点困惑。我这样认为是因为在尝试将其值分配给对象之前的任何时候尝试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 ));

  }
}

既然我们对你的目标一无所知,你确定吗

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

这是唯一一个你的办公室没有人的情况。(因为它不会明显地循环)


所以我敢打赌。

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


此外,一旦您将项目放入officeval数组中,您可能会注意到它的项目比应该的多,因为它不会在循环的每个迭代中显示为清除officeval。这可能是故意的,但我猜不是。问题的根本原因与:

  • 没有意识到javascript通过引用传递复杂的数据类型 (请参阅)(这些帖子是我如何完成传递值而不是引用的指南:,)
  • 在每次内部for循环迭代后不将officeval数组重置回0
  • 为了解决这个问题,我:

  • 将officeval数组的声明移到外部函数之外,以便可以使用this关键字在内部函数中引用它
  • 使用slice方法创建officeval的按值副本,然后将其传递到内部函数中,用于创建新合同并将其添加到contractsList数组中
  • 每次将新合同推送到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;
    
      }
    }
    
    officeval:string[]=[]
    getContracts(){
    此.contractService.getContracts().subscribe(
    (res)=>{
    //let officeval=新数组();
    对于(var x=0;xconsole.log(err))
    控制台日志(“日志记录合同”);
    }
    createContract(id:number,contractName:string,type:string,isEnabled:boolean,
    服务:字符串,列表办公室:字符串[],列表室:字符串[],
    listSeats:string[],CompactItemSentries:string[],CompactItemSowners:string[],CompactItemSSessions:string[]{
    this.contractsList.push(新合同(id、合同名称、类型、isEnabled、,
    服务、列表办公室、列表室、,
    列表席位、合同哨兵、合同监工、合同监工);
    this.officeval.length=0;
    }
    }
    
    是的,我已经认为需要使用officeval.length=0重置officeval,并一直在尝试确定何时进行重置。但是,我把这个问题推到了一边,直到我真正得到了填充的值。另外,如果我把console.log(res[x][z].resources.office.values.length)放在for循环之前,for循环使用它作为计数器,控制台中返回和显示的所有值都是1或更大。您是否尝试过通过控制台调试代码,并在
    officeval.push
    行上放置断点?我将officeval声明移到了getContracts()函数之外,以便可以在createContract()中使用此.officeval引用它。我一直在逐步调试,看到在创建每个契约并将其推送到contractsList数组时设置的值。ListOffice数组在每个契约末尾显示为长度0的原因是,将契约推送到contractsList后,我调用this.officeval.length=0以重置它。重置操作正在重置contractsList中每个contract元素中的值。我确信当res[x][z]时,它总是大于0。resources.office!==未定义。如前所述,如果我将一个console.log(officeval)放在else{officeval.push(“非配置单元策略”)之后,控制台会列出循环每次迭代的值。好的,这样就创建了对象。exists并填充。也许数组和字符串[]之间的转换是奇怪的,但如果我更改aofficeval: 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; } }