如何在Dashboard组件中为Task对象添加关联Goal的goalCategory字段
问题描述
在Angular的DashboardComponent组件中,需要从tasksCollection获取每个Task Item,为其新增goalCategory字段,字段值为通过外键goal_id查询到的Goal对象的分类名称。
尝试代码
// Dashboard Component export class DashboardComponent implements OnInit { goalCategory!:any; // 用于存储通过getGoalCategory方法获取的分类值,计划在tasksArray遍历中赋值 ngOnInit() { this.tasksService.tasksCollection() .pipe( concatMap(tasksArray => { tasksArray = tasksArray.map((item:any) => { this.getGoalCategory(item); // 获取分类的方法 return { goal_id: item.goal_id, description: item.description, id: item.id, isMainGoal: item.isMainGoal, name: item.name, goalCategory: this.goalCategory // 新增字段,期望赋值为Goal的分类名称 } }) return tasksArray; }) ) .subscribe( (tasks:any) => { console.log(tasks); } ) } }
解决方案
你的代码存在两个核心问题:
- 异步操作未等待结果:
getGoalCategory一般是异步请求(比如查询后端或数据库),调用后直接返回对象时,this.goalCategory还未被赋值。 - 共享变量被覆盖:用类级别的
goalCategory存储值,遍历多个task时,后续task的赋值会覆盖之前的结果,导致所有task的goalCategory都是最后一个的值。
正确实现(异步场景)
假设getGoalCategory返回Observable<string>(根据goal_id获取分类名称),可以这样修改:
import { forkJoin } from 'rxjs'; import { concatMap, map } from 'rxjs/operators'; export class DashboardComponent implements OnInit { ngOnInit() { this.tasksService.tasksCollection().pipe( // 用forkJoin批量处理每个task的异步分类查询 concatMap(tasksArray => forkJoin( tasksArray.map(task => this.getGoalCategory(task.goal_id).pipe( // 将分类名称与原task对象合并 map(category => ({ ...task, goalCategory: category })) ) ) ) ) ).subscribe(tasksWithCategory => { console.log(tasksWithCategory); // 可将结果赋值给组件变量用于页面渲染 }); } // 示例:根据goalId获取分类名称的方法(按需调整) private getGoalCategory(goalId: string): Observable<string> { return this.goalsService.getGoalById(goalId).pipe( map(goal => goal.categoryName) // 从Goal对象中提取分类名称字段 ); } }
同步场景简化实现
如果getGoalCategory是同步方法(比如从本地缓存取数据),直接在map中调用即可,无需forkJoin:
this.tasksService.tasksCollection().pipe( map(tasksArray => tasksArray.map(task => ({ ...task, goalCategory: this.getGoalCategory(task.goal_id) })) ) ).subscribe(tasksWithCategory => { console.log(tasksWithCategory); });
内容的提问来源于stack exchange,提问作者Piotr Deja
相关产品推荐
相关产品推荐

