【问题标题】:can't pass an argument in a typescript function无法在打字稿函数中传递参数
【发布时间】:2021-09-27 18:42:50
【问题描述】:

我有一个名为 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);
   // })
    }

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

【问题讨论】:

    标签: javascript angularjs typescript


    【解决方案1】:

    我认为您的变量 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()

    就像你会在变量“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 变量中包含请求中的所有值。并且您确定在获得所有数据之前不会完成对服务的调用。

    我希望它很清楚。我尽量简短,所以不要犹豫,在线查找更多信息。

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

    【讨论】:

    • 感谢您的帮助,非常感谢,当我打印此内容时。Comps 结果是:[] 0: {id: 7, nome: "angular", descrizione: ""} 1 : {id: 8, 名称: "js", 描述: ""} 长度: 2 proto: Array(0)
    • 所以在代码的这一点上,我的数据是可用的(我从数据库中获取它们),当我尝试在 dipendentiService 中打印相同的数据时,它什么也不打印(空行)。无论如何,我不明白我应该在哪里把“Promise.all”放在我的代码中,在这里?:this.CS.getcompetenzabyid(this.optionsChecked[k]).Promise.all().then(data =>{console. log("数据:"+JSON.stringify(data)); this.Comps.push(data); });再次感谢您的帮助
    • Promise.all() 是一个独立于 toPromise() 的函数。我将编辑我的答案以提供有关如何使用它的更多详细信息。为了更清楚,访问数据库可能需要一些时间,并且 Javascript 不会“等待”。这就是为什么“那么”是为了。你告诉你的代码:当我得到这个请求的答案时(我不知道什么时候)这样做。但是,当您的后端正在处理数据时,javascript 会继续执行其余代码。当请求得到解决时,他将回到“当时”。这意味着 Angular 可以在接收数据之前调用您的服务(即使它们已经在您的数据库中)
    • 我会尝试写一个小例子来告诉你如何等待请求完成。但同样,我不能 100% 确定它来自那个。
    猜你喜欢
    • 2022-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 2021-08-23
    • 1970-01-01
    相关资源
    最近更新 更多