ExtJS Grid Panel滚动条自动下滑,无法滚动至顶部的问题求助
修复ExtJS Grid Panel与SubTable插件的滚动异常问题
我之前处理过类似的SubTable插件导致的滚动异常问题,大概率是插件在渲染子表、行展开/折叠时,没有正确维护Grid滚动容器的高度或滚动位置,或者DOM结构异常引发了浏览器的滚动计算错误。结合你的代码,给你几个针对性的修复方案:
1. 修正SubTable的DOM模板结构,避免标签不匹配
你的SubTable插件的rowBodyTpl和renderTable方法存在标签闭合不匹配的问题,这会导致DOM结构异常,进而干扰浏览器的滚动计算:
// 修正rowBodyTpl,移除多余的</tbody> rowBodyTpl: [ '<table class="' + Ext.baseCSSPrefix + 'grid-subtable">', '{%', 'this.owner.renderTable(out, values);', '%}', '</table>' ], // 修正renderTable方法,在最后闭合<tbody> renderTable: function(out, rowValues) { var me = this, columns = me.columns, numColumns = columns.length, associatedRecords = me.getAssociatedRecords(rowValues.record), recCount = associatedRecords.length, rec, column, i, j, value; out.push('<tbody><thead>'); for (j = 0; j < numColumns; j++) { out.push('<th class="' + Ext.baseCSSPrefix + 'grid-subtable-header">', columns[j].text || columns[j].dataIndex, '</th>'); } out.push('</thead>'); if (associatedRecords.length > 1){ associatedRecords = associatedRecords.descSortBy(function(o){ return o.data.lastUpdate }); } for (i = 0; i < recCount; i++) { rec = associatedRecords[i]; out.push('<tr>'); for (j = 0; j < numColumns; j++) { column = columns[j]; if ( column.dataIndex.includes(".")){ var a = column.dataIndex.split("."); value = rec.get(a[0])[a[1]] }else{ value = rec.get(column.dataIndex); } if (column.renderer && column.renderer.call) { value = column.renderer.call(column.scope || me, value, {}, rec); } out.push('<td class="' + Ext.baseCSSPrefix + 'grid-subtable-cell"'); if (column.width != null) { out.push(' style="width:' + column.width + 'px"'); } out.push('><div class="' + Ext.baseCSSPrefix + 'grid-cell-inner">', value, '</div></td>'); } out.push('</tr>'); } // 新增:闭合tbody标签 out.push('</tbody>'); }
2. 缓存关联记录,减少不必要的Grid重绘
你的getAssociatedRecords方法每次都会重新过滤Devices Store的所有数据,频繁的重绘会干扰滚动位置的稳定性。给记录添加缓存,避免重复计算:
getAssociatedRecords: function(record) { // 给记录添加缓存字段,避免每次渲染都重新过滤 if (!record.get('cachedDevices')) { var devices = Ext.Array.filter( Ext.getStore('Devices').data.items, function(r) { return r.get('activeItemFromStore').includes(record.get('id')); } ); // 缓存结果(注意:如果Devices数据更新,需要清除缓存) record.set('cachedDevices', devices); } return record.get('cachedDevices'); }
同时,在Devices Store数据更新时,清除List记录的缓存并刷新视图:
// 在你的Controller或者Store初始化代码中添加 Ext.getStore('Devices').on('update', function(store, updatedRecord) { // 清除所有List记录的缓存 Ext.getStore('MyStore').each(function(listRecord) { listRecord.set('cachedDevices', null); }); // 刷新Grid视图 Ext.getCmp('listId').getView().refresh(); });
3. 在行展开/折叠时维护滚动位置
SubTable插件展开/折叠行时,Grid的总高度会变化,浏览器可能会自动调整滚动位置。通过监听事件,保存并恢复滚动位置:
viewConfig: { listeners: { expandbody: function(rowNode, record, expandRow, eOpts) { var view = this; // 记录当前滚动位置 var scrollTop = view.getEl().getScrollTop(); // 延迟执行,等子表渲染完成后恢复滚动 Ext.defer(function() { view.getEl().setScrollTop(scrollTop); }, 100); }, collapsebody: function(rowNode, record, expandRow, eOpts) { var view = this; var scrollTop = view.getEl().getScrollTop(); Ext.defer(function() { view.getEl().setScrollTop(scrollTop); }, 100); }, }, // ... 你的其他viewConfig代码 }
4. 替换旧的滚动配置,使用ExtJS推荐的scrollable
autoscroll是ExtJS的旧属性,建议替换为官方推荐的scrollable配置,避免属性冲突:
Ext.define('MyApp.view.List', { extend: 'Ext.grid.Panel', xtype: 'listView', // ... 其他配置 scrollable: true, // 启用滚动,替换autoscroll:false // autoscroll: false, // 移除这个旧属性 // ... });
把这些修改结合起来,应该就能解决滚动条自动下滑的问题了。
内容的提问来源于stack exchange,提问作者TheOldBlackbeard
相关产品推荐
相关产品推荐

