Angular中如何处理数组外键:展示关联Meal对象属性
解决Angular中Mealplan关联Meal数据显示的问题
看起来你现在的核心问题是:Mealplan里存的只是Meal的ID数组,而模板只能直接显示ID,没法关联到Meal的具体属性。我来一步步帮你解决这个问题:
第一步:修正数据层的小问题
首先你的InMemoryDataService里有几处小错误,得先改过来,不然数据请求会出问题:
export class InMemoryDataService implements InMemoryDbService { createDb() { const meals = [ { id: 101, name: 'Meal 1', price: 18.00 }, { id: 102, name: 'Meal 2', price: 20.00 }, // 补充缺失的103-105餐食数据,避免显示"未知餐食" { id: 103, name: 'Meal 3', price: 19.00 }, { id: 104, name: 'Meal 4', price: 22.00 }, { id: 105, name: 'Meal 5', price: 21.00 } ]; // 变量名从mensaplan改成mealplan,和返回键名一致 const mealplan = [ {id: 1, mealsPerWeek: [101, 102, 103, 104, 105]}, {id: 2, mealsPerWeek: [105, 104, 103, 102, 101]} ]; // 返回的键名要和上面的变量名匹配,之前的meal是错的,应该是meals return {meals, mealplan}; } }
另外MealPlanService里的URL拼错了,把'api/meaplan'改成'api/mealplan',不然请求不到数据。
第二步:创建Meal服务获取餐食数据
你需要一个单独的服务来获取所有Meal数据,方便后续做ID映射:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { Meal } from './meal'; @Injectable({ providedIn: 'root' }) export class MealService { private mealsUrl = 'api/meals'; constructor(private http: HttpClient) { } getMeals(): Observable<Meal[]> { return this.http.get<Meal[]>(this.mealsUrl); } }
第三步:在组件中关联Meal和Mealplan数据
在你的Mealplan组件里,我们先获取所有Meal数据并构建一个ID映射表,然后把Mealplan里的ID数组转换成对应的Meal对象数组:
import { Component, OnInit } from '@angular/core'; import { Meal } from '../meal'; import { Mealplan } from '../mealplan'; import { MealService } from '../meal.service'; import { MealPlanService } from '../meal-plan.service'; import { forkJoin } from 'rxjs'; @Component({ selector: 'app-mealplan', templateUrl: './mealplan.component.html', styleUrls: ['./mealplan.component.css'] }) export class MealplanComponent implements OnInit { mealplan: Mealplan[] = []; // 用ID作为键存储Meal对象,方便快速查找 private mealMap: { [key: number]: Meal } = {}; constructor( private mealService: MealService, private mealPlanService: MealPlanService ) { } ngOnInit(): void { this.loadAllData(); } loadAllData(): void { // 同时发起两个请求,避免嵌套订阅 forkJoin([ this.mealService.getMeals(), this.mealPlanService.getMealplan() ]).subscribe(([meals, mealplans]) => { // 构建ID到Meal的映射 meals.forEach(meal => { this.mealMap[meal.id] = meal; }); // 把每个Mealplan的ID数组转换成Meal对象数组 this.mealplan = mealplans.map(plan => ({ ...plan, mealsPerWeek: plan.mealsPerWeek.map(mealId => // 如果ID不存在,返回一个默认的"未知餐食"对象 this.mealMap[mealId] || { id: mealId, name: 'Unknown Meal', price: 0 } ) })); }); } }
第四步:在模板中显示关联后的餐食信息
现在你可以在模板里直接访问Meal的属性了,比如name和price:
<div *ngFor="let plan of mealplan"> <h3>Meal Plan {{ plan.id }}</h3> <p>Meals Per Week:</p> <ul> <li *ngFor="let meal of plan.mealsPerWeek"> {{ meal.name }} ({{ meal.price | currency }}) </li> </ul> </div>
这样处理后,模板就会显示类似Meal 1 (¥18.00), Meal 2 (¥20.00)...的内容,而不是单纯的ID数组了。
内容的提问来源于stack exchange,提问作者Cenasa
相关产品推荐
相关产品推荐

