如何在Thingsboard自定义部件中访问MatTableDataSource?
ThingsBoard自定义部件访问MatTableDataSource实现方案
问题原因
ThingsBoard自定义部件的沙箱默认仅对外暴露@angular/material的部分常用组件、指令,MatTableDataSource属于@angular/material/table二级入口下的工具类,未加入默认暴露列表,直接从@angular/material根路径导入会触发报错。
可落地实现方式
方式1:指定精确导入路径直接引入
3.4及以上版本的ThingsBoard已经支持二级入口导入,不要从@angular/material根路径导入,直接指定table模块的入口即可正常使用:// 替换原有错误的导入路径 import { MatTableDataSource } from '@angular/material/table';导入后可直接按照官方文档写法绑定分页、排序、过滤逻辑,和普通Angular项目用法完全一致。
方式2:从运行时已加载模块提取构造函数
如果上述导入触发运行时找不到模块的报错,说明当前TB版本未开放该二级入口的导入权限,可直接从Angular已加载的模块缓存中提取MatTableDataSource构造函数,无需重复打包依赖:// 放在部件初始化生命周期(ngOnInit/onInit)中执行 declare const ng: any; let MatTableDataSource: any; // 遍历已加载的所有NgModule找到MatTableModule for (const moduleRef of ng.core.NgModuleRef.allModules) { const moduleClass = moduleRef.instance.constructor; if (moduleClass.name !== 'MatTableModule') continue; // 从模块导出列表中匹配MatTableDataSource构造函数 const exportList = moduleRef._exports || moduleClass.ɵmod.exports; for (const exportItem of exportList) { if (exportItem?.name === 'MatTableDataSource') { MatTableDataSource = exportItem; break; } } if (MatTableDataSource) break; } // 正常初始化使用,所有原生API均可用 this.dataSource = new MatTableDataSource(yourRawTableData); // 绑定分页器、排序实例 this.dataSource.paginator = this.paginator; this.dataSource.sort = this.sort; // 过滤逻辑直接赋值filter属性即可生效 // this.dataSource.filter = 'keyword'3.3及更早版本的ThingsBoard如果找不到
ng.core.NgModuleRef.allModules,可遍历window.ng对象下的模块缓存节点,核心逻辑一致,只要定位到MatTableModule的导出列表即可拿到对应构造函数。方式3:内置精简实现(稳定性最高)
如果不想依赖运行时模块结构,可直接将MatTableDataSource的核心逻辑(数据监听、排序、分页、过滤规则)复制到部件代码中,核心代码仅100余行,完全不依赖外部导入,不会随TB版本升级出现兼容问题。
内容的提问来源于stack exchange,提问作者pooley1994
相关产品推荐
相关产品推荐

