我是Angular 4的初学者。 我想以EUR货币计算总发票, 我有价格值和每个价格的货币类型。当我想计算总金额时,我需要调用exchangeService service以获得货币汇率。
当我检查invoicesSumTotalValue的值时,它为0。 这是我的代码:
calcInvTotalValue(){
let prods = (<FormArray>(<FormGroup>(<FormArray>this.productData.parent.parent).parent).controls['products']);
let invoicesSumTotalValue = 0;
prods.controls.forEach(c => {
let price = (<FormGroup>(<FormGroup>c).controls['selected_products']).controls['price'].value;
let currency = (<FormGroup>(<FormGroup>c).controls['selected_products']).controls['currency'].value;
this.exchangeService.getExchRate(currency, "USD").subscribe(
vl => {
let exRate = vl;
invoicesSumTotalValue = invoicesSumTotalValue + (parseFloat(price) * exRate);
},
(error: any) => console.log(error)
);
});
console.log("iNVOICE total is: " + invoicesSumTotalValue);
如何为prods数组的每个值调用service? 谢谢!
答案 0 :(得分:1)
您应使用RxJS的forkJoin等待Array.forEach()
循环完成,然后返回所有可观察对象。如果您熟悉JavaScript中Promises的用法,它实际上类似于Promise.all。
计算invoicesSumTotalValue
时会遇到问题,因为返回可观察值是一个异步操作,因此forEach
循环的下一次迭代可能会在返回getExchRate()的响应之前执行
这是我建议对您的代码进行的修改。基本上,forkJoin()
循环的所有迭代完成后,我们将使用forEach()
返回可观察值。从那里开始,在返回观测值的subscribe()
块中,我们处理invoicesSumTotalValue
的计算。
const prods = (<FormArray>(<FormGroup>(<FormArray>this.productData.parent.parent).parent).controls['products']);
const observablesList = [];
prods.controls.forEach(c => {
const currency = (<FormGroup>(<FormGroup>c).controls['selected_products']).controls['currency'].value;
observablesList.push(this.exchangeService.getExchRate(currency, 'USD'));
})
forkJoin(observablesList).subscribe(response => {
//console.log(response);
// handle the rest
});
答案 1 :(得分:0)
您正在尝试同步记录一个异步值“ invoicesSumTotalValue”,这就是这里的问题。
将方法级别的变量invoicesSumTotalValue移到类级别,并在HTML模板中打印该值,您将获得实际的总值。
由于http服务返回的价格值是可观察的,因此您在进行console.log时不会立即可用。
按如下所示修改代码,它将可以正常工作:(为了方便起见,我模拟了prod数组以在此处显示结果)
组件代码:
导出类ExchangeComponent实现OnInit {
invoicesSumTotalValue = 0;
constructor(private exchangeService: ExchangeService) { }
ngOnInit() {
this.calcInvTotalValue();
}
calcInvTotalValue() {
let prods = [
{
price: 10,
currency: 'INR'
},
{
price: 20,
currency: 'EUR'
}
];
prods.forEach(c => {
let price = c['price'];
let currency = c['currency'];
this.exchangeService.getExchangeRate("USD", currency).subscribe(
vl => {
let exRate = vl['rates'][currency];
this.invoicesSumTotalValue = this.invoicesSumTotalValue + (parseFloat(String(price)) * parseFloat(exRate));
},
(error: any) => console.log(error)
);
});
}
}
模板代码:
{{invoicesSumTotalValue}}