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

Angular中如何在HTML表格展示4列同属性且不重复数据?

解决Angular中Pokemon TCG API卡牌重复显示问题,实现每行4张不同卡牌布局

问题描述

在Angular系统中调用Pokemon TCG API,需要展示cards.images.small对应的卡牌图片,但当前表格实现导致每张卡牌重复显示4次,无法达成每行4张不同卡牌的布局。

现有代码

<div class="scroll">
        <span class="font-extrabold text-3xl" style="color: #ffcb08;" *ngIf="spinner">Carregando cartas</span>
        <table  *ngIf="!spinner" mat-table [dataSource]="dataSource" class="mat-elevation-z8 mat-table">
        
          <ng-container  matColumnDef="position">
            <th mat-header-cell *matHeaderCellDef></th>
            <td (click)="addCard(element)" mat-cell *matCellDef="let element"> <img class="card" [src]="element.images?.small" alt=""> </td>
          </ng-container>
          <ng-container  matColumnDef="position2">
            <th mat-header-cell *matHeaderCellDef></th>
            <td (click)="addCard(element)" mat-cell *matCellDef="let element"> <img class="card" [src]="element.images?.small" alt=""> </td>
          </ng-container>
          <ng-container  matColumnDef="position3">
            <th mat-header-cell *matHeaderCellDef></th>
            <td (click)="addCard(element)" mat-cell *matCellDef="let element"> <img class="card" [src]="element.images?.small" alt=""> </td>
          </ng-container>
          <ng-container  matColumnDef="position4">
            <th mat-header-cell *matHeaderCellDef></th>
            <td (click)="addCard(element)" mat-cell *matCellDef="let element"> <img class="card" [src]="element.images?.small" alt=""> </td>
          </ng-container>
          <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
          <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
        
        </table>
      </div>

问题原因

当前Mat Table的实现逻辑是将单条卡牌数据渲染到4列中,每一列都绑定了同一个element对象,导致每行的4列显示同一张卡牌。

修复方案

方案1:使用CSS Grid + *ngFor(推荐)

这种方式无需修改数据源结构,通过CSS直接控制网格布局,代码更简洁:

模板代码

<div class="scroll">
  <span class="font-extrabold text-3xl" style="color: #ffcb08;" *ngIf="spinner">加载卡牌中</span>
  <div *ngIf="!spinner" class="card-grid">
    <div (click)="addCard(card)" class="card-item" *ngFor="let card of dataSource">
      <img class="card" [src]="card.images?.small" alt="宝可梦卡牌">
    </div>
  </div>
</div>

CSS样式

.card-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
  padding: 1rem;
}

.card-item {
  cursor: pointer;
}

.card {
  width: 100%;
  height: auto;
}

方案2:改造Mat Table数据源(若必须使用Mat Table)

先在组件中将一维卡牌数组转换为每行4张的二维数组:

组件类代码

transformDataSource(): void {
  const chunkSize = 4;
  this.transformedDataSource = [];
  for (let i = 0; i < this.dataSource.length; i += chunkSize) {
    this.transformedDataSource.push(this.dataSource.slice(i, i + chunkSize));
  }
}

// 在API数据加载完成后调用转换方法
this.pokemonApiService.getCards().subscribe(cards => {
  this.dataSource = cards;
  this.transformDataSource();
  this.spinner = false;
});

修改后的模板代码

<div class="scroll">
  <span class="font-extrabold text-3xl" style="color: #ffcb08;" *ngIf="spinner">加载卡牌中</span>
  <table *ngIf="!spinner" mat-table [dataSource]="transformedDataSource" class="mat-elevation-z8 mat-table">
    <ng-container matColumnDef="col1">
      <th mat-header-cell *matHeaderCellDef></th>
      <td (click)="addCard(row[0])" mat-cell *matCellDef="let row">
        <img *ngIf="row[0]" class="card" [src]="row[0].images?.small" alt="宝可梦卡牌">
      </td>
    </ng-container>
    <ng-container matColumnDef="col2">
      <th mat-header-cell *matHeaderCellDef></th>
      <td (click)="addCard(row[1])" mat-cell *matCellDef="let row">
        <img *ngIf="row[1]" class="card" [src]="row[1].images?.small" alt="宝可梦卡牌">
      </td>
    </ng-container>
    <ng-container matColumnDef="col3">
      <th mat-header-cell *matHeaderCellDef></th>
      <td (click)="addCard(row[2])" mat-cell *matCellDef="let row">
        <img *ngIf="row[2]" class="card" [src]="row[2].images?.small" alt="宝可梦卡牌">
      </td>
    </ng-container>
    <ng-container matColumnDef="col4">
      <th mat-header-cell *matHeaderCellDef></th>
      <td (click)="addCard(row[3])" mat-cell *matCellDef="let row">
        <img *ngIf="row[3]" class="card" [src]="row[3].images?.small" alt="宝可梦卡牌">
      </td>
    </ng-container>
    <tr mat-header-row *matHeaderRowDef="['col1', 'col2', 'col3', 'col4']"></tr>
    <tr mat-row *matRowDef="let row; columns: ['col1', 'col2', 'col3', 'col4'];"></tr>
  </table>
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:56:04