2013-05-08 74 views
2

如果您曾經使用過ExtJs,那麼您可能會遇到惡意的「Can not read property」dom'null「異常。對我來說,這是經常出現內部doInsert(外跟蹤中的最後的14個棧)(ExtJS的代碼):ExtJs異常立即破壞頁面上的所有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組件。所有網格,樹木,菜單,按鈕都會立即被破壞。像click和hover這樣的事件綁定不會執行任何操作或生成異常。

我目前通過首先做一個document.getElementById檢查來緩解這個問題,如果結果是未定義的,那麼我推遲100毫秒,然後再試一次。這是醜陋的,但它的工作原理。這樣做也很昂貴。由於某些頁面變得越來越複雜,越來越多的document.getElementById延遲循環;並且越來越難以追蹤哪個模塊內部沒有測試過getElementById。

這是一團糟。

問:有沒有辦法強制ExtJS優雅地投擲?重寫它的異常處理機制?翻轉「dontBreakTheEntirePage」配置變量?

UPDATE

試圖去direct to Sencha and after a few rebuffs後,我表現出的問題更清楚(我希望):

編輯:煎茶正在放緩我答覆的original thread。如果您對這類錯誤有任何興趣,請加入討論。

  1. 打開文檔(http://docs.sencha.com/extjs/4.1.0/
  2. 打開幾個選項卡(我有內線,Ext.tree.Panel,Ext.menu.Menu,Ext.AbstractComponent和Ext.draw.Color)
  3. 打開Chrome開發工具並查找錯誤。
  4. 在選項卡之間來回切換幾次,作爲完整性檢查。標籤按預期呈現,沒有錯誤。
  5. 現在,讓我們打開頁面。
  6. 返回開發工具。
  7. 切換到控制檯。
  8. 定義自組織方法:

    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); 
        } 
    }; 
    
  9. 定義一個用於拋出異常的方法:

    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' 
         }] 
        }); 
    }; 
    
  10. 執行myExceptionFunction方法在tryCatch包裝:

    tryCatch(myExceptionFunction); 
    
  11. 觀察報告的錯誤:「無法讀取屬性」 dom'null「

  12. 現在開始在打開的選項卡之間來回切換。

  13. 突然間,頁面顯示出一些奇怪的行爲。

  14. 您開始在控制檯中看到新的異常:「Uncaught TypeError:無法讀取屬性'dom'的未定義」選項卡呈現,但出現在意想不到的地方。當前選擇的選項卡並不總是正確更新。

現在,ExtJs的文檔站點實際上可以很好地處理這個錯誤。大部分頁面仍然以您可以應對的方式工作;但在我的情況下,我的頁面已經癱瘓。

我們正在討論已經呈現的內容 - 已經在DOM中。 我無法想象在這一點拋出異常的原因,以打破已經執行的內容。

+0

大聲笑找到那個配置的好運氣:)但是你認真地嘗試了一個圍繞這個容易出錯的函數的try catch塊嗎? – dbrin 2013-05-09 20:37:04

+0

@dbrin我有。顯然,我不允許繼續詳細討論Sencha的討論,因爲我的所有答覆都突然「等待批准」。 http://www.sencha.com/forum/showthread.php?263283-ExtJs-exceptions-immediately-break-all-ExtJs-components-on-a-page – Christopher 2013-05-10 03:35:36

+0

過去一段時間,因爲我用extjs,我懷疑這是這個問題,我想到的唯一原因就是你說你不斷地檢查這些物品是否準備好。 Ext.OnReady()是否有任何幫助,或者它主要用於檢查DOM的初始化是否已完成? – Josh 2013-05-17 18:08:17

回答

1

克里斯托弗,我很抱歉,但埃文對你的問題在你的鏈接線程中的迴應是合適的,並且有很大的意義。他完全理解你所要求的,而你並不理解他。對Extjs如何構建的內在機制的進一步研究會讓你意識到,當你描述它們時,事物「已經呈現」與其他所有與佈局引擎有關的東西緊密相關。這是爲了大大提高渲染速度的微觀優化而完成的。因爲它緊緊地聯繫在一起,所以當你試圖渲染一些不存在的東西時,你會把整個引擎放下來。

這裏的誤解是你認爲事物'已經被渲染'與'被渲染事物'無關'。在extjs中,這些東西是緊密結合的,打破它們會打破另一個。由於這種緊密耦合對於使圖書館渲染速度更快(相信我,他們不能讓它渲染得慢一些,並且仍然可以在IE8上使用),因此您遇到的「問題」是必要的罪惡。

如果您無法或不想花時間在您自己的代碼的邏輯中實現另一個解決方案,Evan的用簡單的try-catch塊圍繞您的代碼的例子是最好的路線。