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

如何从两个API取数并在Angular Material表格中关联显示用户名

解决Angular Material表格关联Posts和Users API显示用户名的问题

问题概述

现有Posts和Users两个API,通过userId字段关联,需要实现类似SQL内连接的效果,在Angular Material表格中显示Posts数据及对应的用户名,但目前无法正常显示username字段。

问题分析

  1. 接口定义存在错误:Users接口中list的类型应为UsersList[]而非List[];
  2. 组件未同时获取两个API的数据,也未执行数据关联逻辑;
  3. 数据源赋值逻辑混乱,未将关联后的数据传入表格;
  4. Posts的userId为字符串类型,Users的userId为数字类型,存在类型不匹配,需转换处理。

解决方案

1. 修复TypeScript接口定义

修正Users接口的类型错误:

import { UsersList} from "./UsersList"

export interface Users{
    list: UsersList[]  // 将List[]改为UsersList[]
    count: number
    success: boolean
}

建议统一userId类型,将PostsList的userId改为数字类型(或在关联时做类型转换):

export interface PostsList {
    id: number
    title: string
    body: string
    userId: number  // 与UsersList的userId类型统一
}

2. 并行请求API并关联数据

使用RxJS的forkJoin同时请求两个API,获取数据后完成类似内连接的关联操作:

组件代码修改

import { forkJoin } from 'rxjs';
import { MatTableDataSource } from '@angular/material/table';
import { Posts } from './path-to-posts-interface';
import { Users } from './path-to-users-interface';

export class PostsComponent implements OnInit{
  displayedColumns: string[] = ['id', 'title', 'body', 'userId', 'username'];
  dataSource!: MatTableDataSource<any>;
  private postsList: any[] = [];
  private usersList: any[] = [];

  constructor(private myService: MyService){ }

  ngOnInit(): void {
    this.loadJoinedData();
  }

  loadJoinedData(): void {
    forkJoin([
      this.myService.getPosts(),
      this.myService.getUsers()
    ]).subscribe(([postsRes, usersRes]) => {
      this.postsList = postsRes.list;
      this.usersList = usersRes.list;
      
      // 关联数据,匹配对应的用户名
      const joinedData = this.postsList.map(post => {
        // 处理userId类型转换(如果未修改接口类型的话)
        const user = this.usersList.find(u => u.userId === parseInt(post.userId));
        return {
          ...post,
          username: user ? user.username : 'Unknown'
        };
      });

      this.dataSource = new MatTableDataSource(joinedData);
    });
  }
}

3. 修正表格模板绑定

修改模板的数据源绑定,确保使用关联后的dataSource:

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
    <ng-container matColumnDef="id">
      <th mat-header-cell *matHeaderCellDef> ID</th>
      <td mat-cell *matCellDef="let element">{{element.id}}</td>
    </ng-container>

    <ng-container matColumnDef="title">
      <th mat-header-cell *matHeaderCellDef> 标题</th>
      <td mat-cell *matCellDef="let element">{{element.title}}</td>
    </ng-container>
  
    <ng-container matColumnDef="body">
      <th mat-header-cell *matHeaderCellDef> 内容</th>
      <td mat-cell *matCellDef="let element">{{element.body}}</td>
    </ng-container>
  
    <ng-container matColumnDef="userId">
      <th mat-header-cell *matHeaderCellDef> 用户ID </th>
      <td mat-cell *matCellDef="let element">{{element.userId}}</td>
    </ng-container>

    <ng-container matColumnDef="username">
      <th mat-header-cell *matHeaderCellDef> 用户名 </th>
      <td mat-cell *matCellDef="let element">{{element.username}}</td>
    </ng-container>
  
    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

4. 可选:添加类型安全的关联接口

为保证类型安全,可创建新接口定义关联后的数据结构:

import { PostsList } from "./PostsList";

export interface PostWithUser extends PostsList {
    username: string;
}

然后在组件中替换数据源类型:

dataSource!: MatTableDataSource<PostWithUser>;

// 关联数据时指定类型
const joinedData: PostWithUser[] = this.postsList.map(post => {
  const user = this.usersList.find(u => u.userId === parseInt(post.userId));
  return {
    ...post,
    username: user ? user.username : 'Unknown'
  };
});

内容的提问来源于stack exchange,提问作者Kareem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 09:28:14