2008-08-31 5 views
0

Принимая Jeff Atwood's advice, я решил использовать библиотеку JavaScript для самого базового приложения, которое я пишу. Я выбрал Dojo toolkit, версия 1.1.1. Сначала все было в порядке: код перетаскивания, который я написал, работал в первый раз, вы можете перетаскивать задачи на экране, чтобы изменить порядок их приоритета, и каждая операция перетаскивания вызывает обработчик событий, который отправляет AJAX позвоните на сервер, чтобы сообщить, что заказ был изменен.Обработка событий в Dojo

Затем я пошел добавлять функции отслеживания электронной почты. Стандартные вещи: новые входящие письма имеют уникальный идентификационный номер, прикрепленный к их теме, все последующие сообщения об этой проблеме можно отслеживать, просто оставив этот идентификационный номер в теме при ответе. Итак, у нас есть список открытых задач, каждый со своим идентификационным номером, и каждая из этих задач имеет упорядоченный по времени список связанных писем. Я хотел, чтобы текст этих писем был доступен пользователю, поскольку они смотрели на их список задач, поэтому я сделал каждый блок задач элементом управления «Дерево» Dijit - верхний уровень содержит описание задачи, ветви содержат даты электронной почты и один «лист» от каждого из этих ветвей содержит текст электронной почты.

Первая проблема: я хотел, чтобы древовидное представление было полностью свернуто по умолчанию. После тщательного поиска Google я нашел ряд решений, все из которых, казалось, были действительны для предыдущих версий Dojo, но не для тех, которые я использовал. В конечном итоге я понял, что лучшим решением, казалось бы, было бы вызвать обработчик событий, когда загрузился элемент управления Tree, который просто свернул каждую ветвь/лист. К сожалению, несмотря на то, что элемент управления Tree был создан и вызван обработчик события «startup», ветви и листья все еще не загружены (данные все еще загружаются через вызов AJAX). Таким образом, я изменил систему так, чтобы весь текст электронной почты и структура дерева были добавлены на стороне сервера. Это означает, что весь полностью заполненный элемент управления Tree доступен, когда вызывается обработчик события запуска.

Итак, обработчик события запуска полностью разрушает дерево. Затем я не смог найти «правильный» способ иметь хороший отформатированный текст для публикации по электронной почте. Я могу поместить текст электронной почты в листе только в порядке, но любой HTML выйдет и появится на веб-странице. Купите больше рыться вокруг документации Dojo (как правило, устарели, с кодом и примерами для версий до версии 1.0) и Google. В конце концов я придумал решение о том, чтобы запустить JavaScript и прочитать элемент SPAN, который находится внутри каждого листового узла, и не убирать экранированный HTML-код в его innerHTML. Я подумал, что я бы поставил код, чтобы сделать это с помощью кода полного коллапса-дерева, в обработчике события запуска Tree Control.

Однако ... оказывается, что элемент SPAN фактически не создается до тех пор, пока пользователь не нажмет на него расширение (маленький символ «+» в дереве, который вы нажмете, чтобы развернуть узел). Хорошо, справедливо - я добавлю код повторного форматирования в обработчик события onExpand() или что бы он ни называл. Который, кажется, не существует. Я искал документацию, я искал Google ... Я вполне вероятно неправильно понимаю Dojo's «публиковать/подписывать» систему обработки событий, но я думаю, что в основном потому, что, похоже, нет какой-либо всеобъемлющей документации для это где угодно (например, где я могу узнать, какие события я могу подписаться?).

Итак, лучшим решением, которое я могу придумать, является добавление обработчика события onClick (а не события «Dojo», но простого события JavaScript, о котором Dojo ничего не знает) в узел expando каждого Дерево, которое переформатирует HTML внутри элемента SPAN каждого листа. За исключением ... когда это называется, элемент 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 Tree правильно.
  • Правильный способ обработки событий Dojo, например, где я могу выяснить, какие события доступны для меня, чтобы подписаться.
  • Лучшая библиотека JavaScript для использования (могу ли я делать то, что хочу с помощью JQuery, и избегать подхода «все вокруг дома», увиденного выше?).

PS: Если вы назвали проект программного обеспечения, подумайте об уникальности его имени в Google - я уверен, что поиск документации «Dojo» в Google будет проще, если все результаты боевых искусств не будут получены в путь.

PPS: Firefox spellchecker умеет называть «Atwood», исправляя меня, когда я кладу два «T» вместо одного. Джефф сейчас знаменит?

ответ

3

Я предполагаю, что вы следовали руководству dijit.Tree and dojo.data in Dojo 1.1, которое направило вас на передачу данных в элемент управления дерева с помощью хранилища данных. Это заставило меня постучать головой о кирпичную стену.

Это не очень хороший подход, и альтернатива на самом деле не очень хорошо документирована. Вместо этого вам нужно создать модель использования. Я привел пример ниже древовидной модели, созданной для отображения структуры каталога LDAP.

Вы найдете стандартную реализацию модели в своем распределении додзе на ./dijit/_tree/model.js. Комментарии должны помочь вам понять функции, поддерживаемые моделью.

Класс IDirectoryService, приведенный ниже, является заглушкой для серверных Java POJO, созданных Direct Web Remoting (DWR). Я настоятельно рекомендую DWR, если вы собираетесь делать много взаимодействия клиент-сервер.

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

И вот выдержка из моей страницы JSP, где я создал модель и использовал ее для заполнения дерева.

 
<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> 
Смежные вопросы