2

ExtJ を使用したことがある場合は、おそらく「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 に直接アクセスしようとした後、いくつかの拒否の後、問題をより明確に示しました (希望):

編集: Sencha は元のスレッドへの私の返信をモデレートしています。このクラスの障害に興味がある場合は、ディスカッションに追加してください。

  1. ドキュメントを開きます ( http://docs.sencha.com/extjs/4.1.0/ )
  2. いくつかのタブを開きます (Ext、Ext.tree.Panel、Ext.menu.Menu、Ext.AbstractComponent、および Ext.draw.Color があります)。
  3. Chrome Dev Tools を開き、エラーを探します。
  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. tryCatch ラッパーで myExceptionFunction メソッドを実行します。

    tryCatch(myExceptionFunction);
    
  11. 報告されたエラーを観察します:「null のプロパティ 'dom' を読み取れません」

  12. 開いているタブの間を行ったり来たりクリックし始めます。

  13. 突然、ページが奇妙な動作を示しています。

  14. コンソールに新しい例外が表示されるようになります: 「Uncaught TypeError: Cannot read property 'dom' of undefined」現在選択されているタブが常に適切に更新されるとは限りません。

現在、ExtJs のドキュメンテーション サイトは、実際にこの障害を非常にうまく処理しています。ページの大部分は、まだ対処できる方法で機能します。しかし、私のシナリオでは、私のページは不自由です。

既にレンダリングされたコンテンツ、つまり既に DOM にあるコンテンツについて話しているのです。その時点を過ぎて例外がスローされ、既に実行されたものを壊す理由は想像できません。

4

1 に答える 1

1

クリストファー、申し訳ありませんが、リンクされたスレッドの質問に対するエヴァンの回答はすべて適切であり、非常に理にかなっています. 彼はあなたが求めていることを完全に理解していますが、あなたは彼を理解していません。Extjs がどのように構築されているかの内部メカニズムをさらに調査すると、「既にレンダリングされている」ものは、​​レイアウト エンジンに関係する他のすべてのものと密接に関連していることがわかります。これは、レンダリング速度を大幅に向上させるマイクロ最適化のために行われます。互いに非常に密接にリンクしているため、何かを存在しない別のものにレンダリングしようとすると、エンジン全体がダウンします。

ここでの誤解は、「既にレンダリングされた」ものは「レンダリングされる」ものとは何の関係もないというあなたの仮定です。extjs では、これらは密接に結合されており、一方が壊れると他方も壊れます。この密結合はライブラリのレンダリングを高速化するために必要であるため (これ以上レンダリングを遅くしても IE8 で使用できるようにすることはできません)、あなたが抱えている「問題」は必要悪です。

単純な try-catch ブロックでコードを囲む Evan の例は、独自のコードのロジック内に別のソリューションを実装するために開発時間を費やすことができない、またはしたくない場合に最適な方法です。

于 2013-05-13T20:03:45.387 に答える