问题描述
这可能是一件很基本的事情,做错了,所以您将不得不原谅我的无知,但是我只是在学习Angular,遇到了一个非常烦人的障碍,我似乎无法找到与我的Google搜索相关的任何内容
我正在跟踪一个教程,该教程将获取一些静态JSON数据以收取运输费用,并将其绑定为一个运输组件。我有一个获取数据的服务,看起来像这样,但是我删除了与此问题无关的代码。
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class CartService {
constructor(
private http: HttpClient
) { }
getShippingPrices() {
return this.http.get('/assets/shipping.json');
}
}
运输组件代码如下:
import { Component,OnInit } from '@angular/core';
import { CartService } from '../cart.service';
@Component({
selector: 'app-shipping',templateUrl: './shipping.component.html',styleUrls: ['./shipping.component.css']
})
export class ShippingComponent implements OnInit {
constructor(
private cartService: CartService
) { }
shippingCosts;
ngOnInit() {
this.shippingCosts = this.cartService.getShippingPrices();
}
}
这样的标记:
<div class="shipping-item" *ngFor="let shipping of shippingCosts | async">
<span>{{ shipping.type }}</span>
<span>{{ shipping.price | currency }}</span>
</div>
所有这些都适用于本教程中的示例数据,如下所示:
[
{
"type": "Overnight","price": 25.99
},{
"type": "2-Day","price": 9.99
},{
"type": "Postal","price": 2.99
}
]
但是,我真正想做的是调用一个Web服务,该服务返回的数据更像这样:
{"shipping":[
{
"type": "Overnight","price": 2.99
}
]}
当我上次在分裂之前使用Angular时,现在被称为angularjs,我认为我可以做这样的事情:
<div class="shipping-item" *ngFor="let shipping of shippingCosts.shipping | async">
<span>{{ shipping.type }}</span>
<span>{{ shipping.price | currency }}</span>
</div>
这似乎现在不起作用,它什么也没做,没有错误,没有在浏览器中呈现,没有ajax调用来获取数据,没有任何我可以检测到的东西。
我还认为我可以回溯到史前时代,像这样:
ngOnInit() {
let temp = this.cartService.getShippingPrices();
this.shippingCosts = temp.shipping;
}
与尝试绑定到属性类似,这也没有做任何事情,没有错误,没有呈现任何内容,没有ajax调用来获取数据。
所以我的问题是,我该如何绑定到深入到要返回的数据一级的数组。
解决方法
http请求是异步的。当您这样做
this.shippingCosts = this.cartService.getShippingPrices();
一个Observable存储在shippingCosts中,而不存储在您指定的数据中。您必须执行以下操作
this.cartService.getShippingPrices()
.subscribe(costs => {
this.shippingCosts = cost;
});
我个人喜欢在这种情况下与学生们合作
this.cartService.getShippingPrices().toPromise()
.then(costs => {
this.shippingCosts = cost;
})
.catch(err => {
console.log(err);
});
您还可以将对服务的请求移至异步方法,然后像这样调用它
async loadShippingCart() {
this.shippingCosts = await this.cartServices.getShippingPrices().toPromise();
}
然后从ngOnInit方法中调用它
希望这可以为您提供帮助
,您的语法在这里是错误的:
<div class="shipping-item" *ngFor="let shipping of shippingCosts.shipping | async">
<span>{{ shipping.type }}</span>
<span>{{ shipping.price | currency }}</span>
</div>
应该是这样的:
<div class="shipping-item" *ngFor="let shipping of (shippingCosts | async)?.shipping">
<span>{{ shipping?.type }}</span>
<span>{{ shipping?.price | currency }}</span>
</div>
所以,事情首先是需要获得与此(shippingCosts | async)
异步的可观察值,然后再从中获得所需的任何值,例如?.shipping
。
奖金提示:当对象属性为null,未定义等(例如?
)时,请始终使用elvis运算符shipping
来避免可能的应用崩溃