Angular8.1.0+ngx-datatable15.0.2报Cannot read property 'indexes'错误求助
Cannot read property 'indexes' of undefined错误 我之前处理过这个版本组合的兼容问题,这个错误本质是ngx-datatable 15.x在配合Angular 8使用时,全选状态管理的内部初始化逻辑存在缺陷——当你开启了selectCheck属性,但组件内部的选中状态对象还未完成初始化时,就会触发allRowsSelected getter的报错。而ngx-datatable 14.x配合Angular 7时,这块逻辑的容错性更好,所以不会出现问题。
下面是几个可行的解决方案,按推荐程度排序:
1. 显式绑定选中状态数组(最推荐)
给组件提供一个初始的空选中数组,确保内部状态对象被正确初始化:
步骤1:在组件类中添加初始选中状态
// 你的组件.ts文件 selected: any[] = [];
步骤2:在模板中绑定selected属性
修改你的ngx-datatable标签,添加[selected]="selected":
<ngx-datatable *ngIf='!containerLoader && (containers | async)?.length!=0' class="bootstrap striped" [rows]="containers|async" [columnMode]="'force'" [headerHeight]="50" [footerHeight]="50" [rowHeight]="'auto'" [externalPaging]="true" [count]="page.totalElements" [offset]="page.pageNumber" [limit]="page.size" (page)='loadData($event)' [selectCheck]="true" [displayCheck]="displayCheck" [loadingIndicator]="loadingIndicator" [selected]="selected" <!-- 新增这行 --> > <!-- 原有列内容保持不变 --> </ngx-datatable>
这个方案直接补全了组件缺失的初始状态,让allRowsSelected getter能访问到合法的对象,从根源解决报错。
2. 优化异步数据的渲染时机
虽然你已经用了*ngIf做判断,但可以进一步优化异步数据的处理,避免组件在数据未完全就绪时开始初始化:
<ngx-datatable *ngIf="!containerLoader && (containers | async) as containers" <!-- 改为局部变量赋值 --> class="bootstrap striped" [rows]="containers" <!-- 直接使用局部变量,避免重复订阅 --> [columnMode]="'force'" [headerHeight]="50" [footerHeight]="50" [rowHeight]="'auto'" [externalPaging]="true" [count]="page.totalElements" [offset]="page.pageNumber" [limit]="page.size" (page)='loadData($event)' [selectCheck]="true" [displayCheck]="displayCheck" [loadingIndicator]="loadingIndicator" > <!-- 原有列内容保持不变 --> </ngx-datatable>
这种方式确保组件只有在异步数据完全加载并赋值后才会渲染,减少组件初始化时的空值风险。
3. 降级ngx-datatable版本
如果暂时不想修改代码,可以把ngx-datatable降级到14.x版本(和你Angular 7时使用的版本一致),这个版本和Angular 8的兼容性更稳定:
npm install @swimlane/ngx-datatable@14 --save
为什么这个错误只出现在Angular 8+15的组合中?
ngx-datatable 15.x版本可能针对Angular 9+的变更做了内部逻辑调整,简化了状态初始化的流程,但没有考虑Angular 8的兼容性,导致在开启行选择功能时,内部的selected状态对象未被正确初始化,进而访问indexes属性时抛出undefined错误。
内容的提问来源于stack exchange,提问作者Khaled Ayed

