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
相关产品推荐
相关产品推荐

