我有一个名为 DipComponent.ts 的组件,在这个组件中我有一个名为 submit 的函数,该函数将 3 个数据传递给另一个页面中名为 DipService.ts(ine 数组,一个数字和另一个数组)的函数。最后一个数组(对象数组)在页面 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);
// })
}
谢谢你,抱歉我的英语不好。
答案 0 :(得分:0)
我认为您的变量 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 中的 Promises 并继续使用 Observables。如果您想了解更多信息,可以查看 Angular 文档和 RxJs 库。
无论如何,除了异步之外,目前我没有看到过多的解释。
编辑:
一个例子向你展示了 await Promises 和 Promise.all() 是如何工作的。但是您可以(并且应该)在网络上找到更多详细的教程。
所以当你这样做时
this.CS.getcompetenzabyid(this.optionsChecked[k]).toPromise()
你会得到一个承诺。这还不是您可以直接使用的值。它将解析并为您提供最终值,但您不知道确切时间。例如,当您从代码运行 SQL 请求时会发生这种情况。您不知道请求需要多长时间。
Javascript 是一种“非阻塞”语言。这意味着它不会等待 DB 回答,它会做其他事情以免浪费时间。在我们的例子中,其他意思是“继续执行代码”。
我们之前获得的 Promise 对象允许 javascript 在它最终到达时处理结果(当发生这种情况时,您的代码可能已经很远了)。
所以要处理这个 Promise,你有两种方法:
then
关键字进行回调。await
来“阻止”代码使用 then
方法(您在代码中使用的方法),您不能强制 javascript 不执行在您之后编写的代码。
但是使用 await
可以。你会写这样的东西:
const data = await this.CS.getcompetenzabyid(this.optionsChecked[k]).toPromise()
就像你会在变量“data”中得到 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 变量中拥有您请求中的所有值。并且您确定在获得所有数据之前不会完成对服务的调用。
我希望它很清楚。我尽量简短,所以不要犹豫,在线查找更多信息。
我希望它能解决您的问题。但即使没有,也可以避免将来出现错误。