Для начала необходимо выбрать источник данных. Будем использовать данные из таблицы DEMO_PAGE_HIERARCHY, создаваемой в числе прочих при установке демонстрационного приложения.
ExtJS имеет возможность асинхронно подгружать элементы дерева по мере раскрытия родительских элементов. Для этого необходим скрипт на http-сервере, который возвращает данные в формате понятном библиотеке ExtJS.
"Родным" форматом в этом случае является JSON, который понимается библиотекой без дополнительных телодвижений со стороны разработчика. Однако в Oracle 10g нет стандартных средств для работы с JSON. Поэтому обратимся за помощью к проекту PL/JSON, который предоставляет набор удобных средств для работы с JSON-данными. Установка PL/JSON затруднений не вызывает, инструкция есть в readme.txt.
Для работы страницы с деревом я написал простую процедуру, которая возвращает дочерние элементы дерева для элемента с заданным идентификатором, который передается в виде единственного параметра в процедуру:
CREATE OR REPLACE PROCEDURE TEST.GET_TREE_NODES(NODE NUMBER) IS ITEM JSON; ITEM_LIST JSON_LIST := JSON_LIST(); BEGIN FOR REC IN( SELECT PAGE_ID ID, PAGE_NAME TEXT FROM DEMO_PAGE_HIERARCHY WHERE PARENT_PAGE_ID = NODE ) LOOP ITEM := JSON(); ITEM.PUT('id', REC.ID); ITEM.PUT('text', REC.TEXT); ITEM_LIST.ADD_ELEM(ITEM.TO_ANYDATA); END LOOP; HTP.P(ITEM_LIST.TO_CHAR()); END;
После этого необходимо предоставить права на запуск процедуры пользователю, от лица которого работает APEX (прописан в соответствующем DAD) и зарегистрировать в функции
Здесь apex_owner - владелец схемы, в которую установлен APEX.
За основу javascript для определения объекта дерева был взят пример с сайта ExtJS и немного изменен. Представленный ниже текст нужно добавить в HTML Header страницы APEX. Первые 3 строки это подключение библиотеки Ext JS.
<link rel="stylesheet" type="text/css" href="http://localhost/ExtJS302/resources/css/ext-all.css"> <script src="http://localhost/ExtJS302/adapter/ext/ext-base.js"></script> <script src="http://localhost/ExtJS302/ext-all-debug.js"></script> <script type="text/javascript"> Ext.onReady(function(){ Ext.BLANK_IMAGE_URL = 'http://localhost/images/s.gif'; var PagesTreeLoader = new Ext.tree.TreeLoader({ dataUrl :"http://localhost:8080/apex/test.get_tree_nodes" }); var PagesTree = new Ext.tree.TreePanel({ title : 'Pages', collapsible : false, animCollapse : false, border : true, id : "tree_pages", el : "mytree", autoScroll : true, animate : false, enableDD : true, containerScroll : true, height : 500, width : 400, loader : PagesTreeLoader }); var PagesTreeRoot = new Ext.tree.AsyncTreeNode({ text : 'Pages', draggable : false, id : '0' // this IS the id of the startnode }); // Render the tree. PagesTree.setRootNode(PagesTreeRoot); PagesTree.render(); PagesTree.expand(); }); </script>Далее нужно создать HTML-регион, в Source которого нужно добавить следующее:
<div id="mytree"> </div>
Это будет служить контейнером для создаваемого дерева. Обратите внимание на строку:
dataUrl :"http://localhost:8080/apex/test.get_tree_nodes"Она указывает дереву, что обращаться за данными для формирования элементов нужно к процедуре GET_TREE_NODES, определенной выше.
Вот и все. Результат на картинке