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

如何在Angular中创建行列标题一致且带绑定复选框的矩阵表格?

问题修复与实现方案

问题分析

  1. 复选框全部联动:当前mat-table的数据源weightMatrix是单元格级别的对象数组,每一行的所有复选框都绑定到同一个element.value,导致选中一个时整行的复选框同步变化。
  2. 首列行标题不匹配:HTML模板中尝试显示element.row,但TableMatrix对象中没有row属性,且行数据的生成逻辑错误,未正确关联行标题。

修复方案

1. 重构数据结构

定义行数据类型,每一行对应一个标题,以及各列的复选框状态:

// 行数据结构:包含行标题和各列的选中状态映射
interface TableRow {
  rowTitle: string;
  rowIndex: number;
  columnValues: { [key: string]: boolean };
}

2. 修正HTML模板

调整表格列定义,首列显示行标题,各列绑定对应列的独立选中状态:

<table mat-table [dataSource]="tableRows" class="mat-elevation-z8">
  <!-- 首列:行标题列 -->
  <ng-container matColumnDef="rowTitle">
    <th mat-header-cell *matHeaderCellDef>#</th>
    <td mat-cell *matCellDef="let row"> {{row.rowTitle}} </td>
  </ng-container>
  
  <!-- 动态列:对应每个自定义标题 -->
  <ng-container *ngFor="let column of weightingComponents" [matColumnDef]="column.name">
    <th mat-header-cell *matHeaderCellDef> {{column.name}} </th>
    <td mat-cell *matCellDef="let row"> 
      <input type="checkbox" [(ngModel)]="row.columnValues[column.name]"> 
    </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

3. 修改组件TS逻辑

重新初始化行数据,确保每个单元格选中状态独立,同时正确设置显示列:

import { Component, Input, OnInit } from '@angular/core';
import { WeightingComponent } from '../weighting/weighting.component';

// 行数据接口
interface TableRow {
  rowTitle: string;
  rowIndex: number;
  columnValues: { [key: string]: boolean };
}

const SET_RULES_POC: string[] = ['Test1', 'Test2', 'Test3'];

@Component({
  selector: 'app-table-component',
  templateUrl: './table-component.html',
  styleUrls: ['./table-component.scss'],
})
export class TableComponent implements OnInit {
  @Input() weightingComponents: WeightingComponent[] = [];
  tableRows: TableRow[] = [];
  displayedColumns: string[] = [];

  ngOnInit(): void {
    // 初始化列标题组件
    for (let i = 0; i < SET_RULES_POC.length; i++) {
      this.weightingComponents.push(new WeightingComponent(SET_RULES_POC[i], i));
    }

    // 生成每行数据,为每个列初始化选中状态(默认false)
    this.tableRows = this.weightingComponents.map((component, rowIndex) => {
      const columnValues: { [key: string]: boolean } = {};
      this.weightingComponents.forEach(col => {
        columnValues[col.name] = false;
        // 可选:如需对角线默认选中,可添加判断
        // columnValues[col.name] = col.position === rowIndex;
      });
      return {
        rowTitle: component.name,
        rowIndex: rowIndex,
        columnValues: columnValues
      };
    });

    // 设置显示列:首列+所有自定义列标题
    this.displayedColumns = ['rowTitle', ...this.weightingComponents.map(col => col.name)];
  }

  // 获取指定单元格的选中状态
  getCellValue(rowIndex: number, columnName: string): boolean {
    return this.tableRows[rowIndex]?.columnValues[columnName] ?? false;
  }

  // 打印所有单元格状态
  logAllValues(): void {
    this.tableRows.forEach(row => {
      console.log(`行 ${row.rowTitle}:`, row.columnValues);
    });
  }
}

4. 关键优化说明

  • 复选框联动修复:每个单元格绑定到row.columnValues[column.name],每个列对应独立的属性,彻底解决联动问题。
  • 首列标题修复:首列直接显示row.rowTitle,与行标题完全匹配。
  • 最佳实践调整:使用TableRow封装行数据,符合Angular Material Table的数据源设计;避免修改全局常量SET_RULES_POC(原代码中unshift('#')会污染全局值)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:10:11