简体   繁体   English

无法在打字稿函数中传递参数

[英]can't pass an argument in a typescript function

i have a component called DipComponent.ts and in this component i have a function named submit, this function pass 3 datas to a function in another page called DipService.ts(ine array, one number and another array).我有一个名为 DipComponent.ts 的组件,在这个组件中我有一个名为 submit 的函数,这个函数将 3 个数据传递给另一个页面中名为 DipService.ts(ine 数组,一个数字和另一个数组)的函数。 the last array(an array of objects) is full of data in the page DipComponent.ts but when i try to read it in the DipService.ts it looks empty.最后一个数组(对象数组)在页面 DipComponent.ts 中充满了数据,但是当我尝试在 DipService.ts 中读取它时,它看起来是空的。 here is my code of DipComponent.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])
  }

}

here is my code of the interested function of DipService.ts:这是我对 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);
   // })
    }

thank you and sorry for my bad english.谢谢你,很抱歉我的英语不好。

I think your variable this.Comps is empty because you fill it in an asynchronous way :我认为您的变量 this.Comps 是空的,因为您以异步方式填充它:

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

So when you do所以当你做

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

Maybe the array is not filled yet.也许数组还没有填满。

What does your console.log(this.Comps) display ?你的console.log(this.Comps)显示什么? If it's an empty array I think it's because of that.如果它是一个空数组,我认为是因为这个。

So in that case you should wait for all the events to finish.因此,在这种情况下,您应该等待所有事件完成。 In your case you use .toPromise() so you could do a Promise.all instead of a forEach.在您的情况下,您使用.toPromise()以便您可以执行 Promise.all 而不是 forEach。

But note that, in most cases, it's recommended to avoid Promises in Angular and to keep using Observables.但请注意,在大多数情况下,建议避免 Angular 中的 Promises 并继续使用 Observables。 You can check the Angular documentation and RxJs library if you want to know more about that.如果您想了解更多信息,可以查看 Angular 文档和 RxJs 库。

Anyway for now I don't see over explanations besides asynchronism.无论如何,除了异步之外,现在我没有看到过多的解释。

EDIT:编辑:

An example to show you how await Promises and Promise.all() work.向您展示 await Promises 和 Promise.all() 如何工作的示例。 But you can (and should) find much more detailed tutorials about that on the web.但是您可以(并且应该)在网络上找到关于此的更详细的教程。

So when you do this.CS.getcompetenzabyid(this.optionsChecked[k]).toPromise() you will get a promise.因此,当您执行this.CS.getcompetenzabyid(this.optionsChecked[k]).toPromise()您将得到一个承诺。 It's not a value you can directly use yet.这还不是您可以直接使用的值。 It will resolve and give you the final value but you don't know exactly when.它将解析并为您提供最终值,但您不知道确切时间。 For example, it's what happens when you run a SQL request from your code.例如,当您从代码运行 SQL 请求时会发生这种情况。 You don't know how long the request will take.你不知道这个请求需要多长时间。

And Javascript is a "non-blocking" language. Javascript 是一种“非阻塞”语言。 This means it will not wait for the DB to answer, it does something else to not waste time.这意味着它不会等待 DB 回答,它会做其他事情以免浪费时间。 And in our case something else means "Continue to execute the code".在我们的例子中,其他意思是“继续执行代码”。

The Promise object we get before allow javascript to take care of the result when it finally arrive (and when that happens you can be really far in your code already).我们之前获得的 Promise 对象允许 javascript 在它最终到达时处理结果(当发生这种情况时,您的代码可能已经很远了)。

So to take care of this Promise you have 2 ways :所以要处理这个 Promise,你有两种方法:

  • Or you give a callback to the then keyword.或者你给then关键字一个回调。
  • Or you use the keyword await to "block" the code或者您使用关键字await来“阻止”代码

With the then approach (what you used in your code) you can't force javascript to not execute the code written after your then.使用then方法(您在代码中使用的方法),您不能强制 javascript 不执行 then 之后编写的代码。

But with the await you can.但是有了await你可以。 You would write something like that :你会写这样的东西:

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

Like that you would get the result of the Promise (when it's resolved) in the variable "data".像那样,您将在变量“data”中获得 Promise 的结果(当它被解析时)。 And with the await keyword javascript will wait the result without executing anymore code.并且使用await关键字,javascript 将等待结果而不执行任何代码。

So to sum up you can just write:所以总结一下你可以写:

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

And you will be sure that this.Comps will be up to date.您将确信 this.Comps 将是最新的。 If you have only one request to do.如果您只有一个请求要做。

But in your case you have few promises because you do few requests in your forEach.但是在您的情况下,您几乎没有承诺,因为您在 forEach 中执行的请求很少。 So you need to wait for all of them.所以你需要等待所有这些。 For that we can use the function Promise.all() that will wait all the Promises you give him.为此,我们可以使用函数 Promise.all() 来等待您给他的所有 Promise。

So in your case :所以在你的情况下:


    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;

Like this you should have all the values from your request in the Comps variable.像这样,您应该在 Comps 变量中拥有您的请求中的所有值。 And you sure that the call to the service will not be done before you get all the datas.并且您确定在获得所有数据之前不会完成对服务的调用。

I hope it's clear.我希望很清楚。 I tried to make it short so don't hesitate to look for more informations online.我试图让它简短,所以不要犹豫,在网上寻找更多信息。

And I hope it will solve your issue.我希望它能解决你的问题。 But even if it doesn't it can avoid bugs in the future.但即使没有,它也可以避免将来出现错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 似乎无法将函数传递给node.js中的setTimeout参数数组(TypeScript) - Can't seem to pass function to setTimeout argument array in node.js (TypeScript) 无法将变量作为onClick函数中的参数传递 - Can't pass a variable as an argument in a onClick function 为什么 Typescript 不能推断出可选 arguments 的 function 参数类型? - Why can't Typescript infer function argument types for optional arguments? 无法传递作为setTimeout函数传递的匿名函数的参数 - can't pass an argument of anonymous function that is passed as setTimeout function 无法将父函数参数传递给子匿名函数 - Can't pass parent function argument to child anonymous function 不能将 var(这是一个函数)作为另一个函数的参数传递 - Can't pass var (which is a function) as argument in another function 无法将回调 function 从 SocketIO 传递到 typescript - Can't pass callback function from SocketIO to typescript typescript 参数不能在获取中使用任何参数? - typescript argument can't use any in fetch? TypeScript 将数组作为参数传递 - TypeScript pass an array as argument javascript/typescript - 通过 eslint 规则强制将 object 作为 function 参数传递 - javascript/typescript - force to pass object as function argument by eslint rule
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM