You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 11:17:46