Angular中如何用Model Adapter模式映射嵌套API JSON至模型并转换格式
Angular中Model Adapter模式实现及嵌套JSON转换方案
一、Model Adapter模式实现嵌套JSON到模型映射
1. 定义层级数据模型
先把嵌套JSON拆解为对应的TypeScript类,明确数据结构:
// 月度投资数据模型 export class MonthlyData { constructor( public invested: number, public earned: number ) {} } // 年度投资数据模型 export class YearlyInvestment { constructor( public year: number, public stockMarket: MonthlyData[] ) {} }
2. 实现Adapter转换类
Adapter负责将API返回的嵌套JSON转换为上述模型实例,核心是遍历嵌套结构提取数据:
import { YearlyInvestment, MonthlyData } from './models'; export class InvestmentAdapter { adapt(apiResponse: any[]): YearlyInvestment[] { return apiResponse.map(item => { // 提取年份(每个对象的唯一键) const year = parseInt(Object.keys(item)[0]); const stockMarketRaw = item[year].stock_market; // 转换月度原始数据为MonthlyData实例数组 const monthlyDataList = Object.entries(stockMarketRaw).map(([_month, data]) => new MonthlyData(parseFloat(data.invested), parseFloat(data.earned)) ); return new YearlyInvestment(year, monthlyDataList); }); } }
3. 在组件中使用Adapter
在Angular组件中实例化或注入Adapter,处理API响应:
import { Component, OnInit } from '@angular/core'; import { InvestmentAdapter, YearlyInvestment } from './models'; @Component({ selector: 'app-investment-stats', templateUrl: './investment-stats.component.html' }) export class InvestmentStatsComponent implements OnInit { investments: YearlyInvestment[] = []; constructor(private adapter: InvestmentAdapter) {} ngOnInit(): void { // 模拟API返回的嵌套JSON数据 const apiResponse = [ {"2023": {"stock_market": {"January": {"invested": "337","earned": "332.8"},"February": {"invested": "306","earned": "299.4"},"March": {"invested": "334","earned": "332.0"},"April": {"invested": "324","earned": "319.7"}}}}, {"2024": {"stock_market": {"January": {"invested": "337","earned": "332.8"},"February": {"invested": "306","earned": "299.4"},"March": {"invested": "334","earned": "332.0"},"April": {"invested": "324","earned": "319.7"}}}} ]; this.investments = this.adapter.adapt(apiResponse); } }
二、嵌套JSON转换为指定统计格式
基于Adapter转换后的模型数据,计算统计指标并生成目标格式:
export function calculateInvestmentStats(investments: YearlyInvestment[]) { // 计算总投入金额 const totalInvested = investments.reduce((yearTotal, yearData) => { return yearTotal + yearData.stockMarket.reduce((monthTotal, month) => monthTotal + month.invested, 0); }, 0); // 计算总收益金额 const totalEarned = investments.reduce((yearTotal, yearData) => { return yearTotal + yearData.stockMarket.reduce((monthTotal, month) => monthTotal + month.earned, 0); }, 0); // 计算回报率(保留1位小数) const returnRate = (((totalEarned - totalInvested) / totalInvested) * 100); const returnPercentage = `${returnRate.toFixed(1)}%`; // 返回目标统计格式 return { totalInvested: totalInvested.toString(), returnPercentage: returnPercentage, description: 'from last year', interpretation: totalEarned >= totalInvested ? 'good returns' : 'poor returns', title: 'Total profit or loss' }; }
在组件中调用统计方法
// 在InvestmentStatsComponent的ngOnInit方法中添加 const stats = calculateInvestmentStats(this.investments); console.log(stats); // 输出结果与目标格式完全匹配
内容的提问来源于stack exchange,提问作者miks
相关产品推荐
相关产品推荐

