Angular 5:如何用ngFor遍历API返回的嵌套对象数组属性?
解决Angular中ngFor遍历Cryptocompare API嵌套数据的问题
我帮你梳理下当前代码的问题,咱们一步步来搞定数据遍历展示的需求:
1. 先搞懂API返回的数据结构
你调用的top/totalvol接口返回的不是直接的数组,而是一个包裹着数组的对象——真正的币种列表数据存在Data属性里。控制台打印的res大概是这样的结构:
{ "Response": "Success", "Message": "", "Type": 100, "Data": [ { "CoinInfo": { "FullName": "Bitcoin", // ...其他币种相关属性 }, "RAW": {...}, "DISPLAY": {...} } ] }
你之前直接把整个响应对象赋值给toplistByTotalVolume,它是个对象而非数组,ngFor自然没法遍历。
2. 修正组件里的数据赋值逻辑
在AppComponent的订阅回调里,要把res.Data(也就是真正的数组)赋值给变量,而不是整个res:
getToplistByTotalVolume() { this._data.serviceToplistByTotalVolume(this.fiatCurrency) .subscribe(res => { // 取出Data数组赋值给遍历用的变量 this.toplistByTotalVolume = res.Data; console.log(res.Data); // 现在打印的就是可遍历的数组了 }); }
3. 调整模板的ngFor位置与属性访问路径
你之前把*ngFor放在<ons-list>上,这会生成多个独立的列表(每个币种一个列表),显然不是你想要的效果。应该把*ngFor移到<ons-list-item>上,这样一个列表里会生成多个列表项。另外,FullName是嵌套在CoinInfo对象里的,模板里要写对访问路径:
<ons-button (click)="getToplistByTotalVolume()">Aktualisieren</ons-button> <ons-list id="crypto-container"> <!-- 将ngFor放在列表项上,遍历每个币种数据 --> <ons-list-item *ngFor="let item of toplistByTotalVolume; index as i"> <div class="center"> <!-- 正确访问CoinInfo下的FullName属性 --> {{ item.CoinInfo.FullName }} </div> </ons-list-item> </ons-list>
4. (可选)优化服务代码与类型规范
你的服务里用map赋值给result2是多余的,HttpClient已经会自动解析JSON并返回Observable,可以简化服务方法:
// ccapi.service.ts serviceToplistByTotalVolume(fiatCurrency: string, exchanger?: string) { // 建议把limit调大一点,比如10,这样能看到更多币种数据 return this._http.get(`https://min-api.cryptocompare.com/data/top/totalvol?limit=10&tsym=${fiatCurrency}`); }
如果想让代码更严谨(避免any类型带来的隐患),还可以定义接口来约束数据类型:
// 在app.component.ts或单独的类型文件中定义接口 interface CoinInfo { Id: string; Name: string; FullName: string; } interface CryptoVolumeItem { CoinInfo: CoinInfo; RAW: any; DISPLAY: any; } interface CryptoVolumeResponse { Response: string; Message: string; Type: number; Data: CryptoVolumeItem[]; } // 组件中修改变量类型 toplistByTotalVolume: CryptoVolumeItem[] = []; // 服务方法指定返回类型 serviceToplistByTotalVolume(fiatCurrency: string, exchanger?: string): Observable<CryptoVolumeResponse> { return this._http.get<CryptoVolumeResponse>(`https://min-api.cryptocompare.com/data/top/totalvol?limit=10&tsym=${fiatCurrency}`); }
这样TypeScript会帮你做类型校验,避免拼写错误之类的低级问题。
现在再运行代码,就能正确遍历并展示每个币种的FullName啦!
内容的提问来源于stack exchange,提问作者Michael Usw
相关产品推荐
相关产品推荐

