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

PrimeNG动态表格循环中如何单独禁用指定行的multiselect下拉选项

问题根源

你当前所有行的多选组件都绑定了同一个data数组,JavaScript中对象是引用类型,数组里的选项对象被所有行共享,只要修改任意一个对象的disabled属性,所有引用该对象的组件都会同步更新,所以会出现修改一行全表生效、同时污染原始数据源的问题。你之前只单独新建FormControl没用,是因为options的引用还是共享的。

解决方案

1. 定义不可修改的基础选项模板

把原来的data作为基础模板,永远不要直接修改它,也不要直接绑定给组件:

// 基础选项模板,只读不修改
const baseOptions = [
  { key: "ALL", desc: "All", disabled: false },
  { key: "PQR", desc: "Pqr", disabled: false },
  { key: "XYZ", desc: "Xyz", disabled: false }
];

2. 新增行时生成独立的options副本

每一行单独持有自己的options数组,新增时对基础模板做深拷贝,切断引用关联:

// 表格渲染用的行数组
tableRows = [];

// 新增行逻辑
addRow() {
  const newRow = {
    // 其他你需要的行字段
    selectControl: new FormControl([]),
    // 深拷贝基础选项,生成当前行独立的选项列表
    options: JSON.parse(JSON.stringify(baseOptions))
  };
  this.tableRows.push(newRow);
}

3. 修改HTML绑定逻辑

循环渲染表格行时,绑定当前行自己的options和FormControl,同时把当前行实例传给变更事件:

<tr *ngFor="let row of tableRows">
  <td>
    <p-multiSelect 
      [options]="row.options" 
      (onChange)="changeEvent($event, row)" 
      optionLabel="desc" 
      dataKey="key" 
      [formControl]="row.selectControl"
    ></p-multiSelect>
  </td>
</tr>

4. 实现变更事件逻辑

只修改当前传入行的options属性,不会影响其他行和原始数据源:

changeEvent(event, currentRow) {
  const selectedKeys = event.value.map(item => item.key);
  const hasAllSelected = selectedKeys.includes('ALL');
  // 仅更新当前行的选项禁用状态
  currentRow.options.forEach(option => {
    if (option.key !== 'ALL') {
      option.disabled = hasAllSelected;
    }
  });
  // 可选:选中ALL时清空其他选中值,仅保留ALL选项
  if (hasAllSelected) {
    currentRow.selectControl.setValue([
      currentRow.options.find(opt => opt.key === 'ALL')
    ]);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 04:48:03