Frage

Ich nehme Jeff Atwoods Beratung, habe ich beschlossen, eine JavaScript-Bibliothek für die sehr einfache To-Do-Listen-Anwendung zu verwenden, die ich schreibe.Ich habe das ausgewählt Dojo-Toolkit, Version 1.1.1.Zuerst war alles in Ordnung:Der Drag-and-Drop-Code, den ich geschrieben habe, hat beim ersten Mal funktioniert. Sie können Aufgaben auf dem Bildschirm ziehen, um ihre Rangfolge zu ändern, und jeder Drag-and-Drop-Vorgang ruft einen Ereignishandler auf, der einen AJAX-Aufruf an den Server sendet, um dies zuzulassen wissen, dass die Reihenfolge geändert wurde.

Dann habe ich die E-Mail-Tracking-Funktionalität hinzugefügt.Standardmaterial:Bei neu eingehenden E-Mails ist an die Betreffzeile eine eindeutige ID-Nummer angehängt. Alle nachfolgenden E-Mails zu diesem Problem können nachverfolgt werden, indem Sie bei der Antwort einfach diese ID-Nummer im Betreff belassen.Wir haben also eine Liste offener Aufgaben, jede mit ihrer eigenen ID-Nummer, und jede dieser Aufgaben verfügt über eine zeitlich geordnete Liste der zugehörigen E-Mails.Ich wollte, dass der Text dieser E-Mails für den Benutzer verfügbar ist, während er seine Aufgabenliste durchsieht, also habe ich jedes Aufgabenfeld zu einem Dijit-„Baum“-Steuerelement gemacht – die oberste Ebene enthält die Aufgabenbeschreibung, Zweige enthalten E-Mail-Daten und a Ein einzelnes „Blatt“ jedes dieser Zweige enthält den E-Mail-Text.

Erstes Problem:Ich wollte, dass die Baumansicht standardmäßig vollständig ausgeblendet ist.Nachdem ich ausführlich bei Google gesucht hatte, fand ich eine Reihe von Lösungen, die alle für frühere Versionen von Dojo gültig zu sein schienen, nicht jedoch für die, die ich verwendete.Irgendwann habe ich herausgefunden, dass die beste Lösung darin zu bestehen scheint, einen Event-Handler zu haben, der nach dem Laden des Tree-Steuerelements aufgerufen wird und einfach jeden Zweig/jedes Blatt ausblendet.Leider wurden die Zweige und Blätter immer noch nicht geladen, obwohl das Tree-Steuerelement instanziiert und sein „Startup“-Ereignishandler aufgerufen wurde (die Daten wurden immer noch über einen AJAX-Aufruf geladen).Deshalb habe ich das System so geändert, dass der gesamte E-Mail-Text und die Baumstruktur serverseitig hinzugefügt werden.Dies bedeutet, dass das gesamte vollständig ausgefüllte Tree-Steuerelement verfügbar ist, wenn sein Startereignishandler aufgerufen wird.

Der Start-Event-Handler reduziert also den Baum vollständig.Als nächstes konnte ich keinen „richtigen“ Weg finden, einen schön formatierten Text für die E-Mail-Blätter zu erstellen.Ich kann den E-Mail-Text problemlos in das Blatt einfügen, aber jeglicher HTML-Code wird maskiert und auf der Webseite angezeigt.Stöbern Sie weiter in der Dojo-Dokumentation (meistens veraltet, mit Code und Beispielen für Versionen vor 1.0) und in Google.Schließlich kam ich auf die Lösung, JavaScript dazu zu bringen, das SPAN-Element zu lesen, das sich in jedem Blattknoten befindet, und das Escapezeichen für den maskierten HTML-Code in seinem innerHTML aufzuheben.Ich dachte, ich würde dafür Code mit dem Code zum vollständigen Zusammenklappen des Baums in den Startereignishandler des Tree-Steuerelements einfügen.

Jedoch...Es stellt sich heraus, dass das SPAN-Element erst erstellt wird, wenn der Benutzer auf das Expando klickt (das kleine „+“-Symbol in einer Baumansicht, auf das Sie klicken, um einen Knoten zu erweitern).Okay, fair genug – ich füge den Neuformatierungscode zum onExpand()-Ereignishandler oder wie auch immer er heißt hinzu.Was es scheinbar nicht gibt.Ich habe nach Dokumentation gesucht, ich habe Google durchsucht ...Möglicherweise verstehe ich Dojos „Publish/Subscribe“-Ereignisverarbeitungssystem falsch, aber ich denke, das liegt hauptsächlich daran, dass es nirgendwo eine umfassende Dokumentation dafür zu geben scheint (z. B. wo finde ich heraus, welche Ereignisse ich abonnieren kann). Zu?).

Letztendlich besteht die beste Lösung, die mir einfallen kann, darin, einen onClick-Ereignishandler (kein „Dojo“-Ereignis, sondern ein einfaches JavaScript-Ereignis, von dem Dojo nichts weiß) zum Expando-Knoten jedes betreffenden Baumzweigs hinzuzufügen -formatiert den HTML-Code im SPAN-Element jedes Blatts.Außer...Wenn das aufgerufen wird, existiert das SPAN-Element immer noch nicht (manchmal – manchmal wurde es zwischengespeichert, nur um Sie noch mehr zu verwirren).Deshalb habe ich im Event-Handler einen Timer eingerichtet, der regelmäßig eine Funktion aufruft, die prüft, ob das relevante SPAN-Element bereits aufgetaucht ist, bevor es dann neu formatiert wird.

// 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+"');");
    }
}

Das Gesagte fühlt sich wie ein wirklich schrecklicher Trick an, und ich bin mir sicher, dass ich zu Beginn meines Denkprozesses irgendwo die falsche Richtung eingeschlagen habe.Kann mir bitte jemand sagen:

  • Der richtige Weg, um gut formatierten Text in ein Dojo-/Dijit-Baum-Steuerelement einzufügen.
  • Der richtige Umgang mit Dojo-Ereignissen, z. B. wo ich herausfinden kann, welche Ereignisse ich abonnieren kann.
  • Eine bessere zu verwendende JavaScript-Bibliothek (kann ich mit JQuery machen, was ich will, und den oben gezeigten All-around-the-House-Ansatz vermeiden?).

PS:Wenn Sie einem Softwareprojekt einen Namen geben, denken Sie an die Einzigartigkeit seines Namens in Google. Ich bin mir sicher, dass die Suche nach „Dojo“-Dokumentation in Google einfacher wäre, ohne dass all die Kampfsportergebnisse im Weg stehen.

PPS:Die Rechtschreibprüfung von Firefox kann „Atwood“ buchstabieren und korrigiert mich, wenn ich zwei „T“ statt eines setze.Ist Jeff jetzt einfach so berühmt?

War es hilfreich?

Lösung

Ich gehe davon aus, dass Sie dem gefolgt sind dijit.Tree und dojo.data in Dojo 1.1 Tutorial, in dem Sie angewiesen wurden, die Daten mithilfe eines Datenspeichers an das Baumsteuerelement zu übergeben.Das brachte mich eine Zeit lang dazu, mit dem Kopf gegen eine Mauer zu stoßen.

Es ist kein wirklich toller Ansatz und die Alternative ist nicht wirklich gut dokumentiert.Stattdessen müssen Sie ein Nutzungsmodell erstellen.Nachfolgend habe ich ein Beispiel eines Baummodells eingefügt, das ich zur Darstellung der Struktur eines LDAP-Verzeichnisses erstellt habe.

Sie finden die Standardimplementierung des Modells in Ihrer Dojo-Distribution unter ./dijit/_tree/model.js.Die Kommentare sollen Ihnen helfen, die vom Modell unterstützten Funktionen zu verstehen.

Die IDirectoryService-Klasse im folgenden Code sind Stubs für serverseitige Java-POJOs, die von generiert werden Direktes Web-Remoting (DWR).Ich kann DWR wärmstens empfehlen, wenn Sie viel Client-Server-Interaktion durchführen.

dojo.declare("LDAPDirectoryTreeModel", [ dijit.tree.model ], {
    getRoot : function(onItem) {
        IDirectoryService.getRoots( function(roots) {
            onItem(roots[0])
        });
    },

    mayHaveChildren : function(item) {
        return true;
    },

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

    getIdentity : function(item) {
        return item.dn;
    },

    getLabel : function(item) {
        return item.rdn;
    }
});

Und hier ist ein Auszug aus meiner JSP-Seite, auf der ich das Modell erstellt und zum Auffüllen des Baumsteuerelements verwendet habe.

<div
  dojoType="LDAPDirectoryTreeModel"
  jsid="treeModel"
  id="treeModel">
</div>
<div
  jsid="tree"
  id="tree"
  dojoType="dijit.Tree" model="treeModel"
  labelAttr="name"
  label="${directory.host}:${directory.port}">
</div>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top