Angular中使用ngFor生成动态表格失效问题求助
问题描述
我正在使用HTML和Angular(TypeScript)开发,希望根据长度可变的数据动态生成如下格式的表格,且不想使用innerHTML:
<div class="s-table-container"> <table class="s-table"> <thead> <tr> <th>ListAverage1</th> <th>ListAverage2</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>12</td> </tr> <tr> <td>2</td> <td>13</td> </tr> <!-- 更多行... --> </tbody> </table> </div>
数据源为:
let average = { "listAverage1": [1,2,3,4,5,6,7,8], "listAverage2": [12,13,14,15,16,17,18,19] }
我尝试了以下代码,但表格中没有显示任何内容:
<table class="table table-hover table-bordered"> <ng-container matColumnDef="average1"> <th class="large8" mat-mdc-header-cell *matHeaderCellDef> ListAverage1 </th> <tr *ngFor = "let average of this.listAverage.listAverage1"> <td>average</td> </tr> </ng-container> <ng-container matColumnDef="average2"> <th class="large8" mat-mdc-header-cell *matHeaderCellDef> ListAverage2 </th> <tr *ngFor = "let average2 of this.listAverage.listAverage2"> <td>average2</td> </tr> </ng-container> </table>
问题分析
你的代码存在几个关键问题:
- 误用Angular Material指令:
matColumnDef是Material表格的专用指令,必须配合mat-table、mat-header-row等组件才能生效,单独定义列不会渲染内容。 - 循环逻辑错误:给每一列单独循环生成
<tr>,会导致两列的行完全分离,不符合表格一行包含多列的结构。 - 数据绑定错误:模板里直接写
average不会显示变量值,必须用插值表达式{{average}}。
解决方案
这里提供两种实现方式,按需选择:
方式一:普通Angular表格(无需Material)
这种方式简单直接,完全用原生Angular指令实现:
组件类代码
import { Component } from '@angular/core'; @Component({ selector: 'app-average-table', templateUrl: './average-table.component.html', styleUrls: ['./average-table.component.css'] }) export class AverageTableComponent { average = { listAverage1: [1,2,3,4,5,6,7,8], listAverage2: [12,13,14,15,16,17,18,19] }; }
模板代码
<div class="s-table-container"> <table class="s-table"> <thead> <tr> <th>ListAverage1</th> <th>ListAverage2</th> </tr> </thead> <tbody> <!-- 基于其中一个数组的长度循环,用索引取对应位置的两个值 --> <tr *ngFor="let item of average.listAverage1; let i = index"> <td>{{ average.listAverage1[i] }}</td> <td>{{ average.listAverage2[i] }}</td> </tr> </tbody> </table> </div>
方式二:Angular Material表格(正确用法)
如果确实需要用Material表格,得按照它的规范编写:
组件类代码
import { Component } from '@angular/core'; import { MatTableDataSource } from '@angular/material/table'; @Component({ selector: 'app-material-average-table', templateUrl: './material-average-table.component.html', styleUrls: ['./material-average-table.component.css'] }) export class MaterialAverageTableComponent { // 定义要显示的列名 displayedColumns: string[] = ['listAverage1', 'listAverage2']; // 把原始数据转换成Material表格需要的对象数组格式 dataSource = new MatTableDataSource( this.average.listAverage1.map((val, index) => ({ listAverage1: val, listAverage2: this.average.listAverage2[index] })) ); private average = { listAverage1: [1,2,3,4,5,6,7,8], listAverage2: [12,13,14,15,16,17,18,19] }; }
模板代码
<div class="s-table-container"> <table mat-table [dataSource]="dataSource" class="s-table"> <!-- ListAverage1列定义 --> <ng-container matColumnDef="listAverage1"> <th mat-header-cell *matHeaderCellDef> ListAverage1 </th> <td mat-cell *matCellDef="let element"> {{ element.listAverage1 }} </td> </ng-container> <!-- ListAverage2列定义 --> <ng-container matColumnDef="listAverage2"> <th mat-header-cell *matHeaderCellDef> ListAverage2 </th> <td mat-cell *matCellDef="let element"> {{ element.listAverage2 }} </td> </ng-container> <!-- 渲染表头行 --> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <!-- 渲染数据行 --> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table> </div>
内容的提问来源于stack exchange,提问作者dev_jr
相关产品推荐
相关产品推荐

