首页 > 解决方案 > 无法在打字稿函数中传递参数

问题描述

我有一个名为 DipComponent.ts 的组件,在这个组件中我有一个名为 submit 的函数,该函数将 3 个数据传递给另一个名为 DipService.ts 的页面中的函数(一个数组,一个数字和另一个数组)。最后一个数组(对象数组)在页面 DipComponent.ts 中充满了数据,但是当我尝试在 DipService.ts 中读取它时,它看起来是空的。这是我的 DipComponent.ts 代码:

import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { competenza } from '../interfaces/competenza';
import { dipendente } from '../interfaces/dipendente';
import { AssenzeService } from '../services/assenzeservice';
import { CompetenzeService } from '../services/competenzeservice';
import { DipendentiService } from '../services/dipendenteservice';

@Component({
  selector: 'app-modificadip',
  templateUrl: './modificadip.component.html',
  styleUrls: ['./modificadip.component.css']
})
export class ModificadipComponent implements OnInit {
  [x: string]: any;
  public dipendentemodificato: any[] = [];
  public dip: dipendente[] = [];
  public competenze: competenza[]=[];
  public competenzeDip: competenza[]=[];
  public competenzeposs = [];
  public optionsMap=<any>[];
  public optionsChecked = <any>[];
  public options=<any>[];
  public stringtemp: string=''
  public Comps=<any[]>([])
  public idcomp!: number[];



  constructor (private route : ActivatedRoute, public DS:DipendentiService, public 
CS:CompetenzeService, public AS:AssenzeService) {
    var id=this.route.snapshot.params.id

    this.DS.getdipendentebyid(id).toPromise().then(data =>{console.log(data);
      for(let i in data){  
        this.dip.push(data[i]);
      }
    });

this.CS.getcompetenze().toPromise().then(data =>{console.log(data);
  for(let i in data){  
    this.competenze.push(data[i]);

  }
});

this.CS.getcompetenzebyiddipendente(id).toPromise().then(data =>{console.log(data);
  for(let i in data){  
    this.competenzeDip.push(data[i]);
  }
});
}

  ngOnInit(): void {
    this.initOptionsMap();
  }

  submit(login: any){
     console.log("submit dipendente", login)
     for(let i in login){  
     this.dipendentemodificato.push(login[i]);
    }
console.log("modifiche del dipendente: "+this.dipendentemodificato)

//----------------
for(var x in this.optionsMap) {
  if(this.optionsMap[x]) {
      this.optionsChecked.push(x);
  }
}
for (var k = 0; k<this.optionsChecked.length; k++) {
  console.log("id competenza "+this.optionsChecked[k])
  this.CS.getcompetenzabyid(this.optionsChecked[k]).toPromise().then(data =>{console.log("datas: "+JSON.stringify(data));
      this.Comps.push(data);
  });
}
console.log(this.Comps)
//----------------

this.DS.postmoddipendenti(this.dipendentemodificato, this.route.snapshot.params.id, this.Comps)
}



  initOptionsMap() {
    for (var x = 0; x<this.competenze.length; x++) {
        this.optionsMap[x] = true;
   }
 }
  updateCheckedOptions(option:number, event:any) {
    this.optionsMap[option] = event.target.checked;
    console.log("dopo aggiornamento "+this.optionsMap[option])
  }

}

这是我对 DipService.ts 感兴趣的函数的代码:

postmoddipendenti(raw: any,id:number,comp=<any[]>([])){
    console.log("::::::"+ comp)        
    var dip = '{'  +'"id"'+':'+id+','+'"nome"'+':'+'"'+raw[0]+'"'+','+'"cognome"'+':'+'"'+raw[1]+'"'+','+'"data_nascita"'+':'+'"'+raw[2]+'"'+','+'"mail"'+':'+'"'+raw[3]+'"'+','+'"telefono"'+':'+raw[4]+','+'"setCompetenze"'+':'+'[]'  +'}'
    console.log("non json ->"+ dip)
    //const obj = JSON.parse(dip);
    //console.log("obj ->"+ obj)
   

   // this.http.post<any>('http://localhost:8080/postdipendenti', obj).subscribe(
      //  (val) => {console.log("POST call successful value returned in body", val);
   // })
    }

谢谢你,对不起我的英语不好。

标签: javascriptangularjstypescript

解决方案


我认为您的变量 this.Comps 是空的,因为您以异步方式填充它:

this.CS.getcompetenzabyid(this.optionsChecked[k]).toPromise().then(data =>{console.log("datas: "+JSON.stringify(data));
      this.Comps.push(data);
  });

所以当你这样做时

this.DS.postmoddipendenti(this.dipendentemodificato, this.route.snapshot.params.id, this.Comps)

也许数组还没有填充。

你的console.log(this.Comps)显示器是什么?如果它是一个空数组,我认为是因为这个。

因此,在这种情况下,您应该等待所有事件完成。在您的情况下.toPromise(),您可以使用 Promise.all 而不是 forEach。

但请注意,在大多数情况下,建议避免在 Angular 中使用 Promise 并继续使用 Observables。如果您想了解更多信息,可以查看 Angular 文档和 RxJs 库。

无论如何,现在除了异步之外,我还没有看到其他解释。

编辑:

一个向您展示 await Promises 和 Promise.all() 如何工作的示例。但是您可以(并且应该)在网上找到更详细的教程。

所以当你这样做时, this.CS.getcompetenzabyid(this.optionsChecked[k]).toPromise() 你会得到一个承诺。这不是您可以直接使用的值。它会解决并给你最终的价值,但你不知道确切的时间。例如,当您从代码运行 SQL 请求时会发生这种情况。你不知道请求需要多长时间。

Javascript 是一种“非阻塞”语言。这意味着它不会等待数据库回答,它会做一些其他事情来不浪费时间。在我们的例子中,其他的意思是“继续执行代码”。

我们之前获得的 Promise 对象允许 javascript 在结果最终到达时处理结果(当发生这种情况时,您的代码可能已经很远了)。

所以要处理这个 Promise,你有两种方法:

  • 或者你给then关键字一个回调。
  • 或者您使用关键字await“阻止”代码

使用这种then方法(您在代码中使用的),您不能强制 javascript 不执行您之后编写的代码。

但有了await你就可以了。你会写这样的东西:

const data = await this.CS.getcompetenzabyid(this.optionsChecked[k]).toPromise()

像这样,您将在变量“数据”中获得 Promise 的结果(当它被解决时)。并且使用await关键字 javascript 将等待结果而不执行更多代码。

所以总结一下,你可以写:

const data = await this.CS.getcompetenzabyid(this.optionsChecked[k]).toPromise(); this.Comps.push(data);

您将确信 this.Comps 将是最新的。如果你只有一个请求要做。

但是在您的情况下,您几乎没有承诺,因为您在 forEach 中执行的请求很少。所以你需要等待所有这些。为此,我们可以使用函数 Promise.all() 来等待你给他的所有 Promise。

所以在你的情况下:


    const datas = [];
          for (var k = 0; k<this.optionsChecked.length; k++) {
           //create array of Promises
 datas.push(this.CS.getcompetenzabyid(this.optionsChecked[k]).toPromise());
          }
          // Wait for all the promises to resolve and get all the datas
          const resolvedDatas = await Promise.all(datas);
          this.Comps = resolvedDatas;

像这样,您应该在 Comps 变量中包含请求中的所有值。并且您确定在获得所有数据之前不会完成对服务的调用。

我希望这很清楚。我试图让它简短,所以不要犹豫,在网上寻找更多信息。

我希望它能解决你的问题。但即使它没有,它也可以避免将来出现错误。


推荐阅读