Domanda

Prendo quello di Jeff Atwood consiglio, ho deciso di utilizzare una libreria JavaScript per l'applicazione di base dell'elenco delle cose da fare che sto scrivendo.Ho scelto il Kit di strumenti per il Dojo, versione 1.1.1.All'inizio andava tutto bene:il codice di trascinamento della selezione che ho scritto ha funzionato la prima volta, puoi trascinare le attività sullo schermo per modificare il loro ordine di precedenza e ogni operazione di trascinamento della selezione chiama un gestore di eventi che invia una chiamata AJAX al server per consentirlo sapere che l'ordine è stato cambiato.

Poi sono andato ad aggiungere la funzionalità di tracciamento della posta elettronica.Roba standard:le nuove e-mail in arrivo hanno un numero ID univoco allegato alla riga dell'oggetto, tutte le e-mail successive relative a quel problema possono essere monitorate semplicemente lasciando quel numero ID nell'oggetto quando rispondi.Pertanto, abbiamo un elenco di attività aperte, ciascuna con il proprio numero ID e ciascuna di queste attività ha un elenco ordinato nel tempo di e-mail associate.Volevo che il testo di quelle e-mail fosse disponibile per l'utente mentre esaminava l'elenco delle attività, quindi ho creato per ogni casella delle attività un controllo "Albero" Dijit: il livello superiore contiene la descrizione dell'attività, i rami contengono le date delle e-mail e un una singola "foglia" di ciascuno di questi rami contiene il testo dell'e-mail.

Primo problema:Volevo che la visualizzazione ad albero fosse completamente compressa per impostazione predefinita.Dopo aver cercato a fondo su Google, ho trovato una serie di soluzioni, tutte valide per le versioni precedenti di Dojo ma non per quella che stavo utilizzando.Alla fine ho capito che la soluzione migliore sembrerebbe essere quella di avere un gestore di eventi chiamato quando il controllo Tree è stato caricato che semplicemente comprime ogni ramo/foglia.Sfortunatamente, anche se il controllo Tree era stato istanziato e il suo gestore di eventi di "avvio" chiamato, i rami e le foglie non erano ancora stati caricati (i dati venivano ancora caricati tramite una chiamata AJAX).Quindi, ho modificato il sistema in modo che tutto il testo delle email e la struttura ad albero vengano aggiunti sul lato server.Ciò significa che l'intero controllo Tree completamente popolato è disponibile quando viene chiamato il relativo gestore eventi di avvio.

Pertanto, il gestore eventi di avvio comprime completamente l'albero.Successivamente, non sono riuscito a trovare un modo "corretto" per avere un bel testo formattato per le email.Posso inserire correttamente il testo dell'e-mail nella foglia, ma qualsiasi codice HTML viene eliminato e viene visualizzato nella pagina Web.Indica di frugare di più nella documentazione di Dojo (tende ad essere obsoleta, con codice ed esempi per versioni precedenti alla 1.0) e Google.Alla fine ho trovato la soluzione per far sì che JavaScript andasse a leggere l'elemento SPAN che si trova all'interno di ciascun nodo foglia e annullasse l'escape del codice HTML sfuggito nel suo innerHTML.Ho pensato di inserire il codice per eseguire questa operazione con il codice completamente collasso dell'albero, nel gestore dell'evento di avvio del controllo Albero.

Tuttavia...si scopre che l'elemento SPAN non viene effettivamente creato finché l'utente non fa clic sull'espanso (il piccolo simbolo "+" in una visualizzazione ad albero su cui si fa clic per espandere un nodo).Ok, abbastanza giusto: aggiungerò il codice di riformattazione al gestore di eventi onExpand(), o come si chiama.Che non sembra esistere.Ho cercato la documentazione, ho cercato su Google...Molto probabilmente sto fraintendendo il sistema di gestione degli eventi "pubblica/sottoscrivi" di Dojo, ma penso che principalmente perché non sembra esserci alcuna documentazione completa al riguardo da nessuna parte (ad esempio, dove posso sapere a quali eventi posso iscrivermi A?).

Quindi, alla fine, la soluzione migliore che riesco a trovare è aggiungere un gestore di eventi onClick (non un evento "Dojo", ma un semplice evento JavaScript di cui Dojo non sa nulla) al nodo di espansione di ciascun ramo dell'albero che ri -formatta l'HTML all'interno dell'elemento SPAN di ogni foglia.Tranne...quando viene chiamato, l'elemento SPAN continua a non esiste (a volte, altre volte è stato memorizzato nella cache, solo per confonderti ulteriormente).Pertanto, faccio impostare al gestore eventi un timer che chiama periodicamente una funzione che controlla se l'elemento SPAN pertinente è già apparso prima di riformattarlo.

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

Quanto sopra dà la sensazione di un hack davvero orribile, e sono sicuro di aver preso una strada sbagliata da qualche parte all'inizio del mio processo di pensiero.Qualcuno può dirmi:

  • Il modo corretto di procedere per inserire testo ben formattato all'interno di un controllo Dojo/Dijit Tree.
  • Il modo corretto di gestire gli eventi Dojo, ad esempio dove posso capire a quali eventi è possibile iscrivermi.
  • Una libreria JavaScript migliore da utilizzare (posso fare quello che voglio con JQuery ed evitare l'approccio completo visto sopra?).

PS:Se stai dando un nome a un progetto software, pensa all'unicità del suo nome su Google: sono sicuro che cercare la documentazione "Dojo" su Google sarebbe più semplice senza che tutti i risultati delle arti marziali si intromettano.

PP:Il controllo ortografico di Firefox sa come si scrive "Atwood", correggendomi quando metto due "T" invece di una.Jeff è così famoso adesso?

È stato utile?

Soluzione

Presumo che tu abbia seguito il dijit.Tree e dojo.data in Dojo 1.1 tutorial che ti ha indirizzato a passare i dati al controllo dell'albero utilizzando un archivio dati.Questo mi ha fatto sbattere la testa contro un muro di mattoni per un po'.

Non è davvero un ottimo approccio e l'alternativa non è molto ben documentata.È invece necessario creare un modello d'uso.Di seguito ho incluso un esempio di un modello ad albero che ho creato per visualizzare la struttura di una directory LDAP.

Troverai l'implementazione predefinita del modello nella tua distribuzione dojo su ./dijit/_tree/model.js.I commenti dovrebbero aiutarti a comprendere le funzioni supportate dal modello.

La classe IDirectoryService del codice seguente sono stub per POJO Java lato server generati da Web remoto diretto (DWR).Consiglio vivamente DWR se hai intenzione di fare molta interazione client-server.

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;
    }
});

Ed ecco un estratto dalla mia pagina JSP in cui ho creato il modello e l'ho utilizzato per popolare il controllo dell'albero.

<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>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top