Angular 5中如何动态添加/移除表格行列及关联数据?
解决方案:动态绑定表格列与对应数据
我明白你的需求啦!你现在已经实现了通过复选框控制表格列的显示/隐藏,但还没把tabledata里的对应数据渲染到表格行中。咱们只需要调整几个关键点,就能让复选框的选择和表格数据完全对应起来:
关键调整说明
- 统一数据字段映射:你的复选框
columnName和tabledata里的字段命名不匹配(比如input.name对应tabledata里的input_name),所以给每个复选框对象新增dataField属性,直接对应数据里的字段名,方便后续渲染。 - 动态渲染表格行数据:在HTML中,表格行需要根据当前选中的
tableHeader循环渲染每一列的数据,而不是写死空的<td>。 - 保持列顺序一致性:确保
tableHeader始终按key排序,保持列的显示顺序和复选框组的顺序一致。
修改后的 component.ts
import { Component, OnInit, Input } from '@angular/core'; import { MatTableDataSource, MatSort } from '@angular/material'; import { Sort } from '@angular/material'; @Component({ selector: 'export-results', templateUrl: './export-results.component.html', styleUrls: ['./export-results.component.scss'] }) export class ExportResultsComponent implements OnInit { @Input() getExportResults: any; inputCheckBox: any = []; callCheckBox: any = []; tableHeader: any = []; tabledata: any = []; constructor() { // 新增dataField属性,对应tabledata里的实际字段名 this.inputCheckBox = [ { key: 1, value: 'name', defaultChecked: true, columnName: 'input.name', dataField: 'input_name' }, { key: 2, value: 'path', defaultChecked: false, columnName: 'input.path', dataField: 'input_path' } ] this.callCheckBox = [ { key: 3, value: 'name', defaultChecked: true, columnName: 'call.name', dataField: 'call_name' }, { key: 4, value: 'rank', defaultChecked: true, columnName: 'call.rank', dataField: 'call_rank' } ] } ngOnInit() { // 初始化tableHeader时,同步dataField属性 this.tableHeader = [ { key: 1, value: 'inputname', defaultChecked: true, columnName: 'input.name', dataField: 'input_name' }, { key: 4, value: 'rank', defaultChecked: true, columnName: 'call.rank', dataField: 'call_rank' }, ]; // 补充完整数据,让demo效果更清晰 this.tabledata = [ { input_name: 'abc1', input_path: 'path2', call_name: 'aaa', call_rank: 1 }, { input_name: 'abc2', input_path: 'path3', call_name: 'bbb', call_rank: 2 } ] } onSelected(checkboxItem) { let existingItem = this.tableHeader.find(x => x.columnName === checkboxItem.columnName); if (existingItem) { // 取消勾选时移除对应列 const index = this.tableHeader.indexOf(existingItem); if (index > -1) { this.tableHeader.splice(index, 1); } } else { // 勾选时添加对应列 this.tableHeader.push({...checkboxItem}); } // 保持列按key值排序,维持原有顺序 this.tableHeader.sort((a, b) => a.key - b.key); } }
修改后的 component.html
<div> <!-- Select columns section--> <div> <div> <label class="select-columns__label-heading">Select Columns</label> <div> <button class="save-button"></button> </div> </div> <!-- Select columns checkboxes --> <div> <div class="select-columns__check-list"> <h4>Input</h4> <div *ngFor="let input of inputCheckBox" class="mat-checkbox"> <mat-checkbox (change)="onSelected(input)" [(checked)]="input.defaultChecked" name="inputCheckBox1"> {{input.value}} </mat-checkbox> </div> </div> <div class="select-columns__check-list"> <h4>Call</h4> <div *ngFor="let call of callCheckBox" class="mat-checkbox"> <mat-checkbox (change)="onSelected(call)" [(checked)]="call.defaultChecked" name="inputCheckBox"> {{call.value}} </mat-checkbox> </div> </div> </div> </div> <!-- table section--> <div class="select-columns__table"> <table matSort class="export-table"> <tr> <!-- 动态渲染表头 --> <th *ngFor="let header of tableHeader">{{header.columnName}}</th> </tr> <!-- 循环渲染每一行数据 --> <tr *ngFor="let row of tabledata"> <!-- 根据当前选中的表头,动态渲染对应列的数据 --> <td *ngFor="let header of tableHeader">{{row[header.dataField]}}</td> </tr> </table> </div> </div>
重点解释
dataField属性:这个属性是连接复选框和tabledata的核心桥梁,它直接对应数据里的字段名,让HTML模板能通过row[header.dataField]动态获取对应列的数据。- 表格行的动态渲染:通过两层
*ngFor,先循环每一行数据,再循环当前选中的表头列,实现了列数和内容随复选框选择实时变化的效果。 onSelected方法优化:用展开运算符{...checkboxItem}复制复选框对象,避免直接引用原对象可能带来的意外修改问题,同时保持了原有的添加/移除逻辑。
内容的提问来源于stack exchange,提问作者Soumya Behera
相关产品推荐
相关产品推荐

