如何获取Ext.dataview.NestedList组件的可见行数量
Ext.dataview.NestedList可见行总数统计方案
原有写法问题说明
this.getItems().length:该方法返回的是NestedList内部挂载的所有子组件集合,包含顶部工具栏、滚动容器、各层级缓存的列表实例等组件对象,和列表行数量没有关联,结果完全不具备参考性。this.getList(this.getLastNode()).getViewItems().length:该写法存在两个核心问题:一是getViewItems()仅返回当前已渲染到DOM中的列表项,若列表开启了默认的无限滚动模式,视口外未触发渲染的行不会被统计;二是节点切换未完成渲染时调用,会拿到上一层级的残留DOM或者未渲染完成的空结果。
正确实现方案
根据统计需求的不同,对应两种实现逻辑:
统计当前激活层级的所有行总数(含滚动后未出现在视口内的当前层条目)
直接取当前激活列表绑定的Store记录总数即可,这是最稳定、性能最好的方案,不受无限滚动、渲染时机影响:
// 获取当前用户正在浏览的激活状态列表 const activeList = this.getActiveItem(); // 统计当前列表绑定的数据集总条数,即为当前层的行总数 const currentLevelTotalRows = activeList.getStore().getCount();
统计当前视口范围内真实可见的DOM行数量
如果需要统计真正渲染在屏幕可视区域、没有被滚动遮挡的行数量,通过视口范围和已渲染行的位置交叉判断实现:
const activeList = this.getActiveItem(); const scrollable = activeList.getScrollable(); const scrollY = scrollable.getPosition().y; const listHeight = activeList.el.getHeight(); const viewportRange = { top: scrollY, bottom: scrollY + listHeight }; // 过滤出和可视区域有交叉的已渲染行 const visibleDomRows = activeList.getViewItems().filter(rowEl => { const rowTop = rowEl.getY(); const rowBottom = rowTop + rowEl.getHeight(); return rowBottom > viewportRange.top && rowTop < viewportRange.bottom; }); const visibleDomRowCount = visibleDomRows.length;
注意:不要在节点切换、数据加载的过程中直接调用统计逻辑,建议在
activeitemchange事件回调中通过Ext.asap延迟一帧执行,等DOM和数据状态同步完成后再取值,避免拿到错误结果。参考调用示例:this.on('activeitemchange', () => { Ext.asap(() => { // 此处放置上述统计逻辑 }) })
内容的提问来源于stack exchange,提问作者webpuper
相关产品推荐
相关产品推荐

