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

Angular实现表格每行动态添加复选框的技术求助

Angular 实现表格行动态添加自定义复选框解决方案

核心思路

给表格每行维护独立的复选框集合(原有+自定义),通过控制输入框的显示/隐藏状态,实现仅当前行新增复选框的效果。以下提供两种实现方式:模板驱动表单和响应式表单(FormArray)。


方式一:模板驱动表单(简单易实现)

1. 定义行数据结构

在组件中定义每行的模型,包含原有复选框、自定义复选框、输入框状态等:

interface TableRow {
  id: string; // 行标识(如ENMT)
  originalCheckboxes: { label: string; checked: boolean }[]; // 原有复选框
  customCheckboxes: { label: string; checked: boolean }[]; // 自定义复选框
  showInput: boolean; // 是否显示新增输入框
  newCheckboxLabel: string; // 新增复选框的名称输入值
}

2. 初始化表格数据

tableRows: TableRow[] = [
  {
    id: 'ENMT',
    originalCheckboxes: [
      { label: 'Checkbox 1', checked: false },
      { label: 'Checkbox 2', checked: false }
    ],
    customCheckboxes: [],
    showInput: false,
    newCheckboxLabel: ''
  },
  // 可添加其他行数据
];

3. 模板代码实现

<table border="1">
  <thead>
    <tr>
      <th>Category</th>
      <th>Checkboxes</th>
      <th>Action</th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let row of tableRows; let i = index">
      <td>{{ row.id }}</td>
      <td>
        <!-- 渲染原有复选框 -->
        <div *ngFor="let cb of row.originalCheckboxes" style="margin: 4px 0;">
          <input type="checkbox" [(ngModel)]="cb.checked">
          <label>{{ cb.label }}</label>
        </div>
        <!-- 渲染自定义复选框 -->
        <div *ngFor="let cb of row.customCheckboxes" style="margin: 4px 0;">
          <input type="checkbox" [(ngModel)]="cb.checked">
          <label>{{ cb.label }}</label>
        </div>
        <!-- 新增复选框的输入区域 -->
        <div *ngIf="row.showInput" style="margin-top: 8px;">
          <input 
            type="text" 
            [(ngModel)]="row.newCheckboxLabel" 
            placeholder="输入复选框名称"
            style="margin-right: 8px;"
          >
          <button (click)="addCustomCheckbox(i)">提交</button>
          <button (click)="cancelInput(i)" style="margin-left: 4px;">取消</button>
        </div>
      </td>
      <td>
        <button *ngIf="!row.showInput" (click)="showAddInput(i)">Add New checkbox</button>
      </td>
    </tr>
  </tbody>
</table>

4. 组件方法实现

// 显示新增输入框
showAddInput(index: number): void {
  this.tableRows[index].showInput = true;
}

// 取消新增操作
cancelInput(index: number): void {
  const row = this.tableRows[index];
  row.showInput = false;
  row.newCheckboxLabel = '';
}

// 提交新增复选框
addCustomCheckbox(index: number): void {
  const row = this.tableRows[index];
  const label = row.newCheckboxLabel.trim();
  if (label) {
    row.customCheckboxes.push({ label, checked: false });
    row.showInput = false;
    row.newCheckboxLabel = '';
  }
}

方式二:响应式表单(FormArray)

如果需要使用响应式表单,核心是给每行分配独立的FormArray,避免全局FormArray导致的行间干扰。

1. 调整数据结构

import { FormArray, FormControl } from '@angular/forms';

interface TableRow {
  id: string;
  checkboxArray: FormArray; // 当前行的复选框FormArray
  checkboxLabels: string[]; // 存储所有复选框的标签(原有+自定义)
  showInput: boolean;
  newCheckboxLabel: string;
}

2. 初始化数据(依赖FormBuilder)

import { FormBuilder } from '@angular/forms';

constructor(private fb: FormBuilder) {}

tableRows: TableRow[] = [];

ngOnInit(): void {
  // 初始化第一行数据
  this.tableRows.push({
    id: 'ENMT',
    checkboxArray: this.fb.array([
      this.fb.control(false), // 对应原有Checkbox 1
      this.fb.control(false)  // 对应原有Checkbox 2
    ]),
    checkboxLabels: ['Checkbox 1', 'Checkbox 2'],
    showInput: false,
    newCheckboxLabel: ''
  });
}

3. 模板代码

<form [formGroup]="dummyForm"> <!-- 外层表单可省略,或根据需求设置 -->
  <table border="1">
    <thead>
      <tr>
        <th>Category</th>
        <th>Checkboxes</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let row of tableRows; let i = index">
        <td>{{ row.id }}</td>
        <td>
          <!-- 绑定FormArray的复选框 -->
          <div *ngFor="let control of row.checkboxArray.controls; let j = index" style="margin: 4px 0;">
            <input type="checkbox" [formControl]="control">
            <label>{{ row.checkboxLabels[j] }}</label>
          </div>
          <!-- 新增输入区域 -->
          <div *ngIf="row.showInput" style="margin-top: 8px;">
            <input 
              type="text" 
              [(ngModel)]="row.newCheckboxLabel" 
              placeholder="输入复选框名称"
              style="margin-right: 8px;"
            >
            <button (click)="addCustomCheckboxWithFormArray(i)">提交</button>
            <button (click)="cancelInput(i)" style="margin-left: 4px;">取消</button>
          </div>
        </td>
        <td>
          <button *ngIf="!row.showInput" (click)="showAddInput(i)">Add New checkbox</button>
        </td>
      </tr>
    </tbody>
  </table>
</form>

4. 组件方法

showAddInput(index: number): void {
  this.tableRows[index].showInput = true;
}

cancelInput(index: number): void {
  const row = this.tableRows[index];
  row.showInput = false;
  row.newCheckboxLabel = '';
}

addCustomCheckboxWithFormArray(index: number): void {
  const row = this.tableRows[index];
  const label = row.newCheckboxLabel.trim();
  if (label) {
    row.checkboxArray.push(this.fb.control(false));
    row.checkboxLabels.push(label);
    row.showInput = false;
    row.newCheckboxLabel = '';
  }
}

常见问题排查

你之前使用FormArray未得到预期效果,大概率是共用了全局FormArray,导致新增的复选框会渲染到所有行中。只要给每行单独分配FormArray(或独立的复选框集合),就能实现仅当前行新增的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 15:00:50