Question

Prendre celui de Jeff Atwood conseil, j'ai décidé d'utiliser une bibliothèque JavaScript pour l'application de liste de tâches très basique que j'écris.j'ai choisi le Boîte à outils du Dojo, version 1.1.1.Au début, tout allait bien :le code glisser-déposer que j'ai écrit a fonctionné la première fois, vous pouvez faire glisser les tâches à l'écran pour modifier leur ordre de priorité, et chaque opération de glisser-déposer appelle un gestionnaire d'événements qui envoie un appel AJAX au serveur pour le laisser sachez que l'ordre a été modifié.

Ensuite, je suis allé ajouter la fonctionnalité de suivi des e-mails.Trucs standards :les nouveaux e-mails entrants ont un numéro d'identification unique attaché à leur ligne d'objet, tous les e-mails ultérieurs concernant ce problème peuvent être suivis en laissant simplement ce numéro d'identification dans l'objet lorsque vous répondez.Nous avons donc une liste de tâches ouvertes, chacune avec son propre numéro d'identification, et chacune de ces tâches a une liste chronologique d'e-mails associés.Je voulais que le texte de ces e-mails soit disponible pour l'utilisateur lorsqu'il consultait sa liste de tâches, j'ai donc fait de chaque boîte de tâches un contrôle Dijit "Arbre" - le niveau supérieur contient la description de la tâche, les branches contiennent les dates d'e-mail et un une seule « feuille » de chacune de ces branches contient le texte de l’e-mail.

Premier problème :Je voulais que l'arborescence soit entièrement réduite par défaut.Après une recherche assez approfondie sur Google, j'ai trouvé un certain nombre de solutions, qui semblaient toutes valables pour les versions précédentes de Dojo mais pas pour celle que j'utilisais.J'ai finalement compris que la meilleure solution semblerait être d'appeler un gestionnaire d'événements lorsque le contrôle Tree était chargé, ce qui réduirait simplement chaque branche/feuille.Malheureusement, même si le contrôle Tree avait été instancié et son gestionnaire d'événements "démarrage" appelé, les branches et les feuilles n'avaient toujours pas été chargées (les données étaient toujours en cours de chargement via un appel AJAX).J'ai donc modifié le système pour que tout le texte des e-mails et la structure arborescente soient ajoutés côté serveur.Cela signifie que l’intégralité du contrôle Tree entièrement rempli est disponible lorsque son gestionnaire d’événements de démarrage est appelé.

Ainsi, le gestionnaire d’événements de démarrage réduit complètement l’arborescence.Ensuite, je n’ai pas trouvé de moyen « approprié » d’avoir un texte bien formaté pour les feuilles d’e-mail.Je peux très bien mettre le texte de l'e-mail dans la feuille, mais tout code HTML est échappé et apparaît dans la page Web.Pensez à fouiller davantage dans la documentation de Dojo (qui a tendance à être obsolète, avec du code et des exemples pour les versions antérieures à 1.0) et Google.J'ai finalement trouvé la solution consistant à faire en sorte que JavaScript aille lire l'élément SPAN qui se trouve à l'intérieur de chaque nœud feuille et annule l'échappement du code HTML échappé dans son innerHTML.J'ai pensé que je mettrais du code pour faire cela avec le code de réduction complète de l'arborescence, dans le gestionnaire d'événements de démarrage du contrôle Tree.

Cependant...il s'avère que l'élément SPAN n'est réellement créé que lorsque l'utilisateur clique sur le expando (le petit symbole "+" dans une arborescence sur laquelle vous cliquez pour développer un nœud).D'accord, c'est assez juste - j'ajouterai le code de reformatage au gestionnaire d'événements onExpand(), ou quel que soit son nom.Ce qui ne semble pas exister.J'ai cherché dans la documentation, j'ai cherché sur Google...Il est fort possible que je comprenne mal le système de gestion des événements « publier/s'abonner » de Dojo, mais je pense que c'est principalement parce qu'il ne semble y avoir aucune documentation complète à ce sujet (par exemple, où puis-je savoir à quels événements je peux m'abonner) à?).

Donc, en fin de compte, la meilleure solution que je puisse trouver est d'ajouter un gestionnaire d'événements onClick (pas un événement "Dojo", mais un simple événement JavaScript dont Dojo ne sait rien) au nœud expando de chaque branche d'arbre qui concerne -formate le HTML à l'intérieur de l'élément SPAN de chaque feuille.Sauf...lorsque cela est appelé, l'élément SPAN n'existe toujours pas (parfois, d'autres fois, il a été mis en cache, juste pour vous embrouiller davantage).Par conséquent, j'ai demandé au gestionnaire d'événements de configurer une minuterie qui appelle périodiquement une fonction qui vérifie si l'élément SPAN concerné est déjà apparu avant de le reformater.

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

Ce qui précède ressemble à un hack vraiment horrible, et je suis sûr que j'ai dû prendre un mauvais chemin quelque part au début de mon processus de réflexion.Quelqu'un peut-il me dire :

  • La bonne façon de procéder pour placer un texte bien formaté dans un contrôle Dojo/Dijit Tree.
  • La bonne façon de gérer les événements du Dojo, par exemple où je peux déterminer à quels événements je peux m'abonner.
  • Une meilleure bibliothèque JavaScript à utiliser (puis-je faire ce que je veux avec JQuery et éviter l'approche générale vue ci-dessus ?).

PS :Si vous nommez un projet logiciel, réfléchissez au caractère unique de son nom dans Google - je suis sûr que la recherche de documentation "Dojo" dans Google serait plus facile sans que tous les résultats des arts martiaux ne vous gênent.

PP :Le correcteur orthographique de Firefox sait comment épeler "Atwood", me corrigeant lorsque je mets deux "T" au lieu d'un.Jeff est-il si célèbre maintenant ?

Était-ce utile?

La solution

Je suppose que vous avez suivi le dijit.Tree et dojo.data dans Dojo 1.1 tutoriel qui vous a demandé de transmettre les données au contrôle d'arborescence à l'aide d'un magasin de données.Cela m'a fait cogner ma tête contre un mur de briques pendant un moment.

Ce n'est pas vraiment une bonne approche et l'alternative n'est pas vraiment bien documentée.Vous devez plutôt créer un modèle d'utilisation.J'ai inclus ci-dessous un exemple d'un modèle d'arborescence que j'ai créé pour afficher la structure d'un annuaire LDAP.

Vous trouverez l'implémentation par défaut du modèle dans votre distribution dojo à l'adresse ./dijit/_tree/model.js.Les commentaires devraient vous aider à comprendre les fonctions prises en charge par le modèle.

La classe IDirectoryService, le code ci-dessous sont des stubs pour les POJO Java côté serveur générés par Accès Web direct à distance (DWR).Je recommande fortement DWR si vous envisagez de faire beaucoup d'interactions client-serveur.

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

Et voici un extrait de ma page JSP où j'ai créé le modèle et l'ai utilisé pour remplir le contrôle d'arborescence.

<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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top