Angular中如何读取JSON文件并列出所有键值对?
解决步骤
1. 修正TypeScript接口
现有Currencies接口和JSON结构不匹配,JSON是键为货币代码、值为货币名称的键值对对象,需要改成带索引签名的接口:
export interface CurrencyMap { [code: string]: string; }
也可以直接用TypeScript内置的Record<string, string>类型,无需额外定义接口。
2. 实现货币数据服务
在currencies.service.ts中,通过Angular的HttpClient读取JSON文件,返回对应数据的Observable:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { CurrencyMap } from './your-interface-path'; // 替换为实际接口路径 @Injectable({ providedIn: 'root' }) export class CurrenciesService { constructor(private http: HttpClient) {} getCurrencies(): Observable<CurrencyMap> { return this.http.get<CurrencyMap>('assets/currencies.json'); } }
3. 在组件中处理数据并渲染
你之前得到Subscription对象是因为直接赋值了subscribe()的返回值,而非在回调里处理数据。以下提供两种实现方式:
方式1:手动订阅(需管理内存)
在list.component.ts中:
import { Component, OnInit, OnDestroy } from '@angular/core'; import { CurrenciesService } from './currencies.service'; import { Subscription } from 'rxjs'; @Component({ selector: 'app-list', templateUrl: './list.component.html' }) export class ListComponent implements OnInit, OnDestroy { currencyCodes: string[] = []; currencyNames: string[] = []; private dataSub!: Subscription; constructor(private currenciesService: CurrenciesService) {} ngOnInit(): void { this.dataSub = this.currenciesService.getCurrencies().subscribe(map => { // 提取所有货币代码(键) this.currencyCodes = Object.keys(map); // 提取所有货币名称(值) this.currencyNames = Object.values(map); }); } ngOnDestroy(): void { this.dataSub.unsubscribe(); } }
对应模板list.component.html:
<h3>键:</h3> <ul> <li *ngFor="let code of currencyCodes">{{ code }}</li> </ul> <h3>值:</h3> <ul> <li *ngFor="let name of currencyNames">{{ name }}</li> </ul>
方式2:使用Async管道(自动管理订阅)
在list.component.ts中:
import { Component } from '@angular/core'; import { CurrenciesService } from './currencies.service'; import { Observable } from 'rxjs'; import { CurrencyMap } from './your-interface-path'; @Component({ selector: 'app-list', templateUrl: './list.component.html' }) export class ListComponent { currencies$: Observable<CurrencyMap>; constructor(private currenciesService: CurrenciesService) { this.currencies$ = this.currenciesService.getCurrencies(); } getCodes(map: CurrencyMap): string[] { return Object.keys(map); } getNames(map: CurrencyMap): string[] { return Object.values(map); } }
对应模板list.component.html:
<h3>键:</h3> <ul *ngIf="currencies$ | async as currencies"> <li *ngFor="let code of getCodes(currencies)">{{ code }}</li> </ul> <h3>值:</h3> <ul *ngIf="currencies$ | async as currencies"> <li *ngFor="let name of getNames(currencies)">{{ name }}</li> </ul>
必要前置配置
确保在根模块(如AppModule)中导入HttpClientModule,否则HttpClient无法使用:
import { HttpClientModule } from '@angular/common/http'; @NgModule({ imports: [ // 其他模块 HttpClientModule ] }) export class AppModule {}
内容的提问来源于stack exchange,提问作者xRay
相关产品推荐
相关产品推荐

