如果您曾经使用过 ExtJs,那么您可能遇到过“无法读取 null 的属性 'dom'”异常。对我来说,它通常发生在 doInsert 内部(外部跟踪中 14 个堆栈中的最后一个)(ExtJs 的代码):
doInsert: function(el, o, returnElement, pos, sibling, append) {
//<My own comment>: hint: el === null (curiously not undefined?)
el = el.dom || Ext.getDom(el);
var newNode;
...
}
当您尝试将 ExtJs 组件(树、网格、按钮等)附加到尚未在 DOM 中的 DOM 元素时,就会发生这种情况。通常元素在内存中,作为 AJAX 请求的一部分构造,准备好在成功时插入。
问题是当 ExtJS 抛出时,它从根本上破坏了页面中的每个 ExtJs 组件。所有的网格、树、菜单、按钮都会立即被破坏。像点击和悬停这样的事件绑定要么什么都不做,要么产生异常。
我目前通过首先进行 document.getElementById 检查来缓解这种情况,如果结果未定义,那么我会推迟 100 毫秒并重试。这很丑陋,但它有效。做起来也很贵。随着某些页面变得越来越复杂,document.getElementById 延迟循环越来越多;并且越来越难以追踪哪个模块内部的哪个方法没有测试getElementById。
一团糟。
问题:有什么方法可以强制 ExtJS 优雅地抛出?重写它的异常处理机制?翻转“dontBreakTheEntirePage”配置变量?
更新:
在尝试直接去煎茶并经过几次拒绝之后,我更清楚地展示了这个问题(我希望):
编辑: Sencha 正在审核我对原始线程的回复。如果您对此类故障有任何兴趣,请加入讨论。
- 打开文档 ( http://docs.sencha.com/extjs/4.1.0/ )
- 打开几个选项卡(我有 Ext、Ext.tree.Panel、Ext.menu.Menu、Ext.AbstractComponent 和 Ext.draw.Color)
- 打开 Chrome 开发工具并查找错误。
- 在选项卡之间来回单击几次作为健全性检查。选项卡按预期呈现,没有错误。
- 现在,让我们打破页面。
- 回到开发工具。
- 切换到控制台。
定义一个临时方法:
var tryCatch = function (func) { try { func.apply(this, Array.prototype.slice.call(arguments, 1)); } catch (ex) { var e = { type: 'js', message: ex.message, detail: 'JS Error type: ' + ex.type + '<br/>\n' + 'Stack: ' + ex.stack }; console.error(e); } };
定义一个会抛出异常的方法:
var myExceptionFunction = function () { //Demo taken straight from ExtJs docs on Ext.menu.Menu Ext.create('Ext.menu.Menu', { width: 100, margin: '0 0 10 0', floating: false, renderTo: 'thisIdDoesNotExist', //and will break the already rendered page items: [{ text: 'regular item 1' }, { text: 'regular item 2' }, { text: 'regular item 3' }] }); };
在 tryCatch 包装器中执行 myExceptionFunction 方法:
tryCatch(myExceptionFunction);
观察报告的错误:“Cannot read property 'dom' of null”
现在开始在打开的选项卡之间来回单击。
突然,页面出现了一些奇怪的行为。
您开始在控制台中看到新的异常:“Uncaught TypeError: Cannot read property 'dom' of undefined” 选项卡呈现,但在意想不到的地方。当前选择的选项卡并不总是正确更新。
现在,ExtJs 的文档站点实际上很好地处理了这个错误。大多数页面仍然以您可以应付的方式工作;但在我的情况下,我的页面已瘫痪。
我们谈论的是已经渲染的内容——已经在 DOM 中。我无法想象超过该点的异常会破坏已经执行的内容的原因。