Pregunta

Tomando el de Jeff Atwood consejo, Decidí usar una biblioteca de JavaScript para la aplicación de lista de tareas muy básica que estoy escribiendo.elegí el kit de herramientas dojo, versión 1.1.1.Al principio todo iba bien:El código de arrastrar y soltar que escribí funcionó la primera vez, puedes arrastrar tareas en la pantalla para cambiar su orden de precedencia, y cada operación de arrastrar y soltar llama a un controlador de eventos que envía una llamada AJAX al servidor para permitirlo. saber que el orden ha sido cambiado.

Luego fui a agregar la función de seguimiento de correo electrónico.Cosas estándar:Los nuevos correos electrónicos entrantes tienen un número de identificación único adjunto a su línea de asunto; todos los correos electrónicos posteriores sobre ese problema se pueden rastrear simplemente dejando ese número de identificación en el asunto cuando responda.Entonces, tenemos una lista de tareas abiertas, cada una con su propio número de identificación, y cada una de esas tareas tiene una lista ordenada por tiempo de correos electrónicos asociados.Quería que el texto de esos correos electrónicos estuviera disponible para el usuario mientras miraba su lista de tareas, así que convertí cada cuadro de tarea en un control "Árbol" de Dijit: el nivel superior contiene la descripción de la tarea, las ramas contienen fechas de correo electrónico y un Una sola "hoja" de cada una de esas ramas contiene el texto del correo electrónico.

Primer problema:Quería que la vista de árbol estuviera completamente colapsada de forma predeterminada.Después de buscar extensamente en Google, encontré varias soluciones, todas las cuales parecían ser válidas para versiones anteriores de Dojo, pero no para la que estaba usando.Finalmente descubrí que la mejor solución parecería ser llamar a un controlador de eventos cuando el control Árbol se había cargado y que simplemente colapsaba cada rama/hoja.Desafortunadamente, a pesar de que se había creado una instancia del control Árbol y se había llamado a su controlador de eventos de "inicio", las ramas y hojas aún no se habían cargado (los datos todavía se estaban cargando mediante una llamada AJAX).Entonces, modifiqué el sistema para que todo el texto del correo electrónico y la estructura del árbol se agreguen en el lado del servidor.Esto significa que todo el control Árbol completamente poblado está disponible cuando se llama a su controlador de eventos de inicio.

Entonces, el controlador de eventos de inicio colapsa completamente el árbol.Luego, no pude encontrar una manera "adecuada" de tener un texto con un buen formato para las hojas de correo electrónico.Puedo poner el texto del correo electrónico en la hoja sin problemas, pero el HTML se escapa y aparece en la página web.Indique más hurgar en la documentación de Dojo (tiende a estar desactualizada, con código y ejemplos para versiones anteriores a la 1.0) y Google.Finalmente se me ocurrió la solución de hacer que JavaScript leyera el elemento SPAN que está dentro de cada nodo hoja y elimine el escape del código HTML escapado en su HTML interno.Pensé que pondría código para hacer esto con el código de colapso total del árbol, en el controlador de eventos de inicio del control Árbol.

Sin embargo...resulta que el elemento SPAN en realidad no se crea hasta que el usuario hace clic en el expando (el pequeño símbolo "+" en una vista de árbol en el que hace clic para expandir un nodo).Bien, es justo: agregaré el código de reformateo al controlador de eventos onExpand(), o como se llame.Lo cual no parece existir.Busqué documentación, busqué en Google...Es muy posible que no entienda bien el sistema de manejo de eventos de "publicación/suscripción" de Dojo, pero creo que eso se debe principalmente a que no parece haber ninguna documentación completa sobre él en ninguna parte (por ejemplo, ¿dónde puedo saber a qué eventos puedo suscribirme? ¿a?).

Entonces, al final, la mejor solución que se me ocurre es agregar un controlador de eventos onClick (no un evento "Dojo", sino un evento simple de JavaScript del que Dojo no sabe nada) al nodo expandido de cada rama del árbol que re -formatea el HTML dentro del elemento SPAN de cada hoja.Excepto...cuando se llama, el elemento SPAN todavía no existe (a veces, otras veces se ha almacenado en caché, solo para confundirlo aún más).Por lo tanto, hago que el controlador de eventos configure un temporizador que llama periódicamente a una función que verifica si el elemento SPAN relevante ha aparecido antes de volver a formatearlo.

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

Lo anterior parece un truco verdaderamente horrible, y estoy seguro de que debo haber tomado un camino equivocado en algún momento al principio de mi proceso de pensamiento.¿Alguien puede decirme por favor:

  • La forma correcta de colocar texto con un buen formato dentro de un control Dojo/Dijit Tree.
  • La forma correcta de manejar los eventos de Dojo, como dónde puedo averiguar qué eventos están disponibles para suscribirme.
  • Una mejor biblioteca de JavaScript para usar (¿puedo hacer lo que quiero con JQuery y evitar el enfoque generalizado visto anteriormente?).

PD:Si está nombrando un proyecto de software, piense en la singularidad de su nombre en Google; estoy seguro de que buscar documentación de "Dojo" en Google sería más fácil sin que todos los resultados de artes marciales se interpongan en el camino.

PPD:El corrector ortográfico de Firefox sabe cómo escribir "Atwood", corrigiéndome cuando pongo dos "T" en lugar de una.¿Jeff es tan famoso ahora?

¿Fue útil?

Solución

Supongo que seguiste el dijit.Tree y dojo.data en Dojo 1.1 tutorial que le indicó cómo pasar los datos al control de árbol utilizando un almacén de datos.Eso me hizo golpearme la cabeza contra una pared de ladrillos por un tiempo.

Realmente no es un gran enfoque y la alternativa no está muy bien documentada.En su lugar, debe crear un modelo de uso.He incluido un ejemplo a continuación de un modelo de árbol que creé para mostrar la estructura de un directorio LDAP.

Encontrará la implementación predeterminada del modelo en la distribución de su dojo en ./dijit/_tree/model.js.Los comentarios deberían ayudarle a comprender las funciones admitidas por el modelo.

La clase IDirectoryService, el código siguiente, son códigos auxiliares para los POJO de Java del lado del servidor generados por Comunicación remota directa por web (DWR).Recomiendo encarecidamente DWR si va a realizar mucha interacción cliente-servidor.

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

Y aquí hay un extracto de mi página JSP donde creé el modelo y lo usé para completar el control de árbol.

<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>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top