1

Jeff Atwood のアドバイスを受けて、私が作成している非常に基本的な To Do リスト アプリケーションに JavaScript ライブラリを使用することにしました。私はDojo ツールキットのバージョン 1.1.1を選びました。最初はすべて問題ありませんでした。私が書いたドラッグ アンド ドロップ コードは初めて機能し、画面上でタスクをドラッグして優先順位を変更でき、ドラッグ アンド ドロップ操作ごとに AJAX を送信するイベント ハンドラーを呼び出します。サーバーを呼び出して、順序が変更されたことを知らせます。

次に、メール追跡機能を追加しました。標準的なもの: 新しい受信メールには、件名に固有の ID 番号が添付されています。その問題に関する後続のメールはすべて、返信時にその ID 番号を件名に残すだけで追跡できます。そのため、それぞれに独自の ID 番号を持つオープン タスクのリストがあり、これらの各タスクには関連する電子メールの時系列リストがあります。ユーザーがタスクのリストを見ているときに、これらの電子メールのテキストを利用できるようにしたかったので、各タスク ボックスを Dijit の「ツリー」コントロールにしました。トップ レベルにはタスクの説明が含まれ、ブランチには電子メールの日付が含まれ、これらの枝のそれぞれから離れた単一の「葉」には、電子メールのテキストが含まれています。

最初の問題: ツリー ビューをデフォルトで完全に折りたたむようにしたかったのです。Google で広範囲に検索した結果、いくつかの解決策が見つかりました。それらはすべて Dojo の以前のバージョンでは有効であると思われましたが、私が使用していたものでは有効ではありませんでした。最終的に、最善の解決策は、ツリー コントロールがロードされたときにイベント ハンドラーを呼び出して、各ブランチ/リーフを単純に折りたたむことであると考えました。残念ながら、Tree コントロールがインスタンス化され、その "startup" イベント ハンドラーが呼び出されたにもかかわらず、ブランチとリーフはまだ読み込まれていません (データは AJAX 呼び出しによってまだ読み込まれていました)。そのため、すべてのメール テキストとツリー構造がサーバー側に追加されるようにシステムを変更しました。これは、スタートアップ イベント ハンドラーが呼び出されたときに、完全に設定された Tree コントロール全体が使用可能であることを意味します。

そのため、スタートアップ イベント ハンドラーはツリーを完全に折りたたみます。次に、私は、電子メール リーフの書式設定された適切なテキストを作成する「適切な」方法を見つけることができませんでした。電子メールのテキストをリーフにうまく配置できますが、HTML はエスケープされて Web ページに表示されます。Dojo のドキュメント (1.0 より前のバージョンのコードと例で、時代遅れになる傾向があります) と Google についてさらに調べてみてください。私は最終的に、JavaScript を取得して各リーフ ノード内にある SPAN 要素を読み取り、エスケープされた HTML コードを innerHTML でアンエスケープするという解決策を思いつきました。Tree コントロールのスタートアップ イベント ハンドラーで、ツリーを完全に折りたたむコードを使用して、これを行うコードを挿入することにしました。

ただし... SPAN 要素は、ユーザーが expando (ノードを展開するためにクリックするツリー ビューの小さな「+」記号) をクリックするまで実際には作成されないことがわかります。わかりました、まあまあ - 再フォーマット コードを onExpand() イベント ハンドラ、またはそれが呼び出されたものに追加します。存在しないようです。ドキュメントを検索したり、Google を検索したりしました... Dojo の「パブリッシュ/サブスクライブ」イベント処理システムを誤解している可能性が非常に高いですが、それは主に、Dojo に関する包括的なドキュメントがないように思われるためだと思います。それはどこにでもあります (サブスクライブできるイベントはどこで確認できますか?)。

したがって、最終的には、onClick イベント ハンドラー (「Dojo」イベントではなく、Dojo が何も知らないプレーンな JavaScript イベント) を、ツリー ブランチを再構築する各 Tree ブランチの expando ノードに追加するのが最善の解決策です。 -各リーフの SPAN 要素内の HTML をフォーマットします。例外...それが呼び出されたとき、SPAN要素はまだ存在しません(さらに混乱させるために、キャッシュされている場合もあります)。そのため、イベント ハンドラーに、関連する SPAN 要素がまだ再フォーマットされていないかどうかを確認する関数を定期的に呼び出すタイマーを設定させます。

// An event handler called whenever a "email title" tree node is expanded.
function formatTreeNode(nodeID) {
    if (dijit.byId(nodeID).getChildren().length != 0) {
        clearInterval(nodeUpdateIntervalID);
        messageBody = dijit.byId(nodeID).getChildren()[0].labelNode.innerHTML
        if (messageBody.indexOf("<b>Message text:</b>") == -1) {
            messageBody = messageBody.replace(/&gt;/g, ">");
            messageBody = messageBody.replace(/&lt;/g, "<");
            messageBody = messageBody.replace(/&amp;/g, "&");
            dijit.byId(nodeID).getChildren()[0].labelNode.innerHTML = "<b>Message text:</b><div style=\"font-family:courier\">"+messageBody+"</div>";
        }
    }
}

// An event handler called when a tree node has been set up - we changed the default fully-expanded to fully-collapsed.
function setupTree(theTree) {
    dijit.byId("tree-"+theTree).rootNode.collapse();

    messageNode = dijit.byId("tree-"+theTree).rootNode.getChildren();
    for (pl = 0; pl < messageNode.length; pl++) {
        messageNode[pl].collapse();
        messageNode[pl].expandoNode.onclick = eval("nodeUpdateIntervalID = setInterval(\"formatTreeNode('"+messageNode[pl].id+"')\",200); formatTreeNode('"+messageNode[pl].id+"');");
    }
}

上記は本当に恐ろしいハックのように感じられ、思考プロセスの早い段階でどこかで間違った方向に進んだに違いないと感じています。誰か教えてください:

  • Dojo/Dijit ツリー コントロール内に適切に書式設定されたテキストを配置するための正しい方法。
  • Dojo イベントを処理する正しい方法 (サブスクライブできるイベントを見つけられる場所など)。
  • より優れた JavaScript ライブラリを使用できます (JQuery でやりたいことを実行し、上記のような家々を丸ごと回避することはできますか?)。

PS: ソフトウェア プロジェクトに名前を付ける場合は、Google でのその名前の一意性を考慮してください。Google で「Dojo」のドキュメントを検索する方が、すべての格闘技の結果が邪魔にならずに簡単になると確信しています。

PPS: Firefox のスペルチェッカーは "Atwood" のスペルを認識しており、'T' を 1 つではなく 2 つ入力すると修正されます。ジェフは今そんなに有名ですか?

4

1 に答える 1

3

データ ストアを使用してツリー コントロールにデータを渡すように指示された Dojo 1.1 チュートリアルの dijit.Tree および dojo.data に従ったと仮定します。そのため、しばらくの間、レンガの壁に頭をぶつけていました。

それは実際には優れたアプローチではなく、代替手段は十分に文書化されていません。代わりに使用モデルを作成する必要があります。LDAP ディレクトリの構造を表示するために作成したツリー モデルの例を以下に示します。

モデルのデフォルトの実装は、./dijit/_tree/model.js にある Dojo ディストリビューションにあります。コメントは、モデルがサポートする機能を理解するのに役立ちます。

以下のコードの IDirectoryService クラスは、Direct Web Remoting (DWR) によって生成されるサーバー側 Java POJO のスタブです。クライアントとサーバーのやり取りを頻繁に行う場合は、DWR を強くお勧めします。

dojo.declare("LDAPDirectoryTreeModel", [ dijit.tree.model ], {
    getRoot : 関数(onItem) {
        IDirectoryService.getRoots( 関数(ルート) {
            onItem(ルート[0])
        });
    }、

    mayHaveChildren : 関数(項目) {
        true を返します。
    }、

    getChildren : function(parentItem, onComplete) {
        IDirectoryService.getChildrenImpl(parentItem, onComplete);
    }、

    getIdentity : 関数(項目) {
        item.dn を返します。
    }、

    getLabel : 関数(項目) {
        item.rdnを返します。
    }
});

これは、モデルを作成し、それを使用してツリー コントロールに入力した JSP ページからの抜粋です。

<div
  dojoType="LDAPDirectoryTreeModel"
  jsid="ツリーモデル"
  id="ツリーモデル">
</div>
<div
  jsid="ツリー"
  id="ツリー"
  dojoType="dijit.Tree" モデル="treeModel"
  labelAttr="名前"
  label="${directory.host}:${directory.port}">
</div>
于 2008-09-01T00:38:52.973 に答える