В процессе работы над небольшим web-проектом мне потребовался компонент для отображения дерева элементов на странице. Компонент должен позволять развернуть/свернуть узлы дерева, обработать клик по элементу, добавить к дереву новые узлы, в общем предоставлять самые основные функции «treeview».
Условия использования компонента при этом несколько отличаются от «общепринятых» в лучшую сторону — в качестве среды исполнения будут применяться современные (IE9+) браузеры (web-проект предполагается использовать в рамках полностью контролируемой внутренней сети). Еще одним моментом является платформа, на базе которой разрабатывается серверная часть. Это ASP.NET MVC, а значит желательно, чтобы компонент поставлялся в том числе в виде NuGet-пакета, дружественного к типовой структуре каталогов ASP.NET MVC-приложения.
В процессе работы над вопросом я изучил существующие варианты и, как водится, изобрел очередной велосипед, но при этом свой собственный,с блэкджеком и шлюзами.
На момент написания этой статьи, в сети Интернет можно найти шесть наиболее популярных компонентов для отображения дерева элементов.
Некоторые выводы.
Взвесив все «за» и «против», я решил изобрести собственный велосипед со следующими характеристиками: максимально простой, дружественный к стандартному шаблону приложения на базе ASP.NET MVC и Visual Studio 2012, без груза поддержки устаревших браузеров. Велосипед был изобретен. Его отличительными особенностями стали:
Для изолирования CSS правил используется простой, но, на мой взгляд, наиболее правильный подход.
Основной TypeScript-класс
Метод
Использование TypeScript+LESS при реализации компонента помимо прочего существенно упрощает его применение в своих проектах и доработку под свои нужды.
GitHub — github.com/resnyanskiy/js.tree
NuGet — nuget.org/packages/resnyanskiy.js.tree
Условия использования компонента при этом несколько отличаются от «общепринятых» в лучшую сторону — в качестве среды исполнения будут применяться современные (IE9+) браузеры (web-проект предполагается использовать в рамках полностью контролируемой внутренней сети). Еще одним моментом является платформа, на базе которой разрабатывается серверная часть. Это ASP.NET MVC, а значит желательно, чтобы компонент поставлялся в том числе в виде NuGet-пакета, дружественного к типовой структуре каталогов ASP.NET MVC-приложения.
В процессе работы над вопросом я изучил существующие варианты и, как водится, изобрел очередной велосипед, но при этом свой собственный,
На момент написания этой статьи, в сети Интернет можно найти шесть наиболее популярных компонентов для отображения дерева элементов.
- jsTree. Судя по прошлогоднему обсуждению jsTree на хабрахабр, некоторая часть разработчиков отдает предпочтение Dynatree.
- jqTree. Производит наиболее приятное впечатление. Возможно из-за неплохого дизайна и подробной документации.
- jQuery TreeView plugin. Автор сообщает о том, что проект больше активно не развивается и рекомендует использовать jqTree.
- Dynatree.
- dhtmlxTree.
- dTree.
Некоторые выводы.
- Для всех характерны накладные расходы по поддержке старых клиентов.
- Первые четыре требуют для своей работы jquery. Пятый использует свой фреймворк. Только последний является самодостаточным.
- При этом последний представляет собой относительно древнего «динозавра» (2003 год) и доступен только в виде zip-архива.
- Публичный контроль версий присутствует только у первых четырех. При этом на GitHub размещены репозитории только первых трех. Репозиторий Dynatree расположен на Google Code. Тут следует отметить, что судя по всему Dynatree эволюционирует в проект Fancytree, который расположен уже на GitHub.
- Ни один из проектов не включает NuGet-пакет.
Взвесив все «за» и «против», я решил изобрести собственный велосипед со следующими характеристиками: максимально простой, дружественный к стандартному шаблону приложения на базе ASP.NET MVC и Visual Studio 2012, без груза поддержки устаревших браузеров. Велосипед был изобретен. Его отличительными особенностями стали:
- реализация на базе TypeScript и LESS,
- работа с информационной моделью дерева в соответствии с шаблоном Composite.
Для изолирования CSS правил используется простой, но, на мой взгляд, наиболее правильный подход.
- К элементу-контейнеру дерева добавляется имя класса, соответствующее как бы namespace'у.
- Селекторы всех CSS правил для компонента контекстно-дочерние, где в качестве единственно обязательного корневого родителя указан класс из предыдущего пункта.
LESS | CSS |
---|---|
|
|
Tree
имеет три открытых члена.- Метод
updateNode(...)
добавляет элементы в указанный узел. - Свойства
onBranchExpand
иonNodeClick
используются для указания обработчиков соответствующих событий.
renderNodeItemsTo(...)
и toggleNodeItemsVisible(...)
реализуют основную логику. Изменение видимости элементов дерева реализуется посредством добавления/удаления DOM-элементов (для удаления используется Element.removeChild(...)
— jsperf).Метод
toggleNodeItemsVisible(...)
возвращает false
, если указанный узел дерева (JS-объект) не имеет элементов. Благодаря этому условие вызова обработчика onBranchExpand
выглядит довольно лаконично:if(!this.toggleNodeItemsVisible(node) && (this.onBranchExpand instanceof Function)) {
this.onBranchExpand(nodeId);
}
Использование TypeScript+LESS при реализации компонента помимо прочего существенно упрощает его применение в своих проектах и доработку под свои нужды.
GitHub — github.com/resnyanskiy/js.tree
NuGet — nuget.org/packages/resnyanskiy.js.tree