ExtJS 6.6.0.13拖拽树节点触发TypeError的解决方案咨询
解决Ext ViewDragZone afterRepair中的firstChild空值错误
问题根源
调用Ext.Msg.Confirm时,模态对话框会临时改变DOM结构,导致ViewDragZone的afterRepair函数尝试访问的元素已被移除或变为null,从而触发读取firstChild的空值错误。
可行解决方案
方案1:重写ViewDragZone的afterRepair方法,增加空值校验
扩展或直接修改ViewDragZone的afterRepair函数,在访问firstChild前先确认元素有效性:
Ext.define('MyApp.override.tree.ViewDragZone', { override: 'Ext.tree.ViewDragZone', afterRepair: function() { var repairEl = this.repairEl; // 逐层校验元素是否存在,避免空值读取 if (repairEl && repairEl.dom) { var firstChild = repairEl.dom.firstChild; if (firstChild) { // 保留原有的修复逻辑 this.beforeRepair(firstChild); Ext.fly(firstChild).highlight(this.highlightColor); } } this.dragging = false; } });
通过两层空值判断,确保只有在元素存在的情况下才执行后续操作,从根本上避免报错。
方案2:触发确认框前终止拖拽状态
在调用Ext.Msg.Confirm前,手动结束ViewDragZone的拖拽流程,保证DOM元素处于稳定状态:
// 示例共享确认函数 function showConfirmAction() { // 获取目标树视图的拖拽实例 var treeView = Ext.ComponentQuery.query('treeview')[0]; if (!treeView) return; var dragZone = treeView.getDragZone(); // 如果正处于拖拽状态,先终止拖拽 if (dragZone && dragZone.dragging) { dragZone.cancelDrag(); dragZone.dragging = false; } // 弹出确认对话框 Ext.Msg.Confirm('确认操作', '你确定要执行此操作吗?', function(btn) { if (btn === 'yes') { // 执行确认后的业务逻辑 } }); }
这种方法从源头规避了拖拽状态与模态对话框的DOM冲突,确保拖拽修复流程不会被打断。
方案3:延迟执行确认对话框
用Ext.defer延迟弹出确认框,给拖拽修复流程足够时间完成DOM更新:
function showConfirmAction() { // 延迟100毫秒执行,等待拖拽修复完成 Ext.defer(function() { Ext.Msg.Confirm('确认操作', '你确定要执行此操作吗?', function(btn) { if (btn === 'yes') { // 执行确认后的业务逻辑 } }); }, 100); }
该方案实现简单,适合对确认框弹出及时性要求不高的场景,让浏览器有充足时间处理拖拽相关的DOM操作。
内容的提问来源于stack exchange,提问作者Swetha
相关产品推荐
相关产品推荐

