PrimeNG p-table排序失效且列选择无法切换问题咨询
问题原因
你遇到的两个异常由以下核心原因导致:
- 列选择不生效:你给
p-table绑定了[columns]="selectedColumns"控制显示列,但表头、表体的*ngFor遍历的是全量的cols数组,选中状态不会对渲染结果产生影响;同时每次ngOnChanges执行时都会重新生成cols数组的对象实例,多选框选中值的对象引用和新cols的对象引用不匹配,set selectedColumns里的includes判断永远返回false。 - 排序不生效:第一你没有给
p-table根组件开启[sortable]="true"属性;第二你把所有字段都存在document.Indexes子对象下,PrimeNG默认排序会直接从数组项的根属性读取field对应的值,无法识别子对象嵌套的字段。
修复步骤
1. 调整组件类逻辑
export class ResultTableComponent implements OnInit, OnChanges { @Input() response: DocumentsResponseModel; documents: Document[]; dataset: any[]; cols: Cols[] = []; @ViewChild('dt') dt: Table; _selectedColumns: any[]; ngOnChanges(changes: SimpleChanges): void { // 仅当response输入属性真的发生变化时才执行逻辑,避免无效执行 if (!changes.response?.currentValue) return; this.cols = []; const documents = this.response.DOCUMENTS; Object.keys(documents[0].Indexes).forEach(key => { this.cols.push({ field: key, header: key.toUpperCase() }); }) Object.keys(documents[0].SystemFields).forEach(key => { this.cols.push({ field: key, header: key.toUpperCase() }); }) // 把字段拍平到数组项根节点,适配默认排序逻辑 this.documents = this.response.DOCUMENTS.map(doc => { return {...doc, ...doc.Indexes, ...doc.SystemFields} }) this._selectedColumns = [...this.cols]; } @Input() get selectedColumns(): any[] { return this._selectedColumns; } set selectedColumns(val: any[]) { // 按field唯一标识匹配,避免对象引用失效问题 this._selectedColumns = this.cols.filter(col => val.some(selected => selected.field === col.field)); } }
2. 调整模板绑定逻辑
<p-table [value]="documents" [paginator]="true" [rows]="5" [columns]="selectedColumns" [showCurrentPageReport]="true" [responsive]="true" [resizableColumns]="true" [sortable]="true" currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries" [rowsPerPageOptions]="[10,25,50]"> <ng-template pTemplate="caption"> <p-multiSelect [options]="cols" [(ngModel)]="selectedColumns" optionLabel="header" selectedItemsLabel="{0} columns selected" [style]="{minWidth: '200px'}" placeholder="Choose Columns"></p-multiSelect> </ng-template> <ng-template pTemplate="header"> <tr> <!-- 遍历选中的列而非全量列 --> <th *ngFor="let col of selectedColumns" pSortableColumn="{{col.field}}"> {{ col.header }} <p-sortIcon field="{{col.field}}"></p-sortIcon> </th> </tr> </ng-template> <ng-template pTemplate="body" let-document> <tr> <!-- 遍历选中的列而非全量列,直接从根节点取字段 --> <td *ngFor="let col of selectedColumns"> <span> {{ document[col.field] }}</span> </td> </tr> </ng-template> </p-table>
内容的提问来源于stack exchange,提问作者davidvera
相关产品推荐
相关产品推荐

