| 开发人员:Application Express
构建 Ajax 内存树
作者:Scott Spendolini
学习如何在 Oracle Application Express 中逐步创建基于 Ajax 的内存树。
到现在为止,您可能听说过 Ajax(Asynchronous JavaScript and XML 的缩写)。如果您使用过 Google Maps、Yahoo Mail 和 Flickr,便会体会到创建丰富的、交互式 UI 的可能性。
Ajax 本身并不是一项技术,而是通过网页实现的多种技术(HTML、CSS、JavaScript 和 XML)的组合。从本质上而言,Ajax 就是将类似客户端-服务器这样的功能扩展到了 Web。
在本文中,您将学习如何基于任何包含层次数据的表在 Oracle Application Express(以前的 HTML DB)中构建一个基于 Ajax 的内存树。(该内存树的代码基于 Application Express 开发小组成员 Carl Backstrom 提供的示例应用程序。)我之所以在此处增加了“内存”一词,是因为与 Carl 的示例不同,该树将“记住”在各个页面视图中展开、折叠以及选定的节点。此外,还有一个搜索功能,用于定位树中的任何节点并相应地将其展开 — 这是一个使用 Application Express 提供的树组件无法实现的功能。当树使用 Ajax 获取展开的节点时,它可以轻松地伸缩以支持一个具有数千或更多行的表。
要求
- 可以访问 Oracle Application Express 2.0 工作区
可以通过在 http://apex.oracle.com 上请求一个免费工作区或安装 Oracle 数据库 10g 快捷版 (XE)(只限 Windows 和 Linux)来快速访问这样的工作区。请注意,早期版本(1.5 和 1.6)将不起作用。
- 一个包含层次数据(ID、父 ID、名称)的表
如果没有以这种方式对数据进行了格式化的表,则可以使用 EMP 演示表。
第 1 步:创建所需的表、序列和触发器
首先,登录到 Application Express 工作区,并创建树所需的数据库对象。TREE_TEMP 表将跟踪针对每个用户展开的树节点。每当用户单击树中的 + 或 - 图标时,该表将通过 JavaScript 和应用程序级进程自动进行异步填充。
从 SQL Workshop 中:
- 使用您的 Workspace Name、 Username 和 Password 登录(如果使用 Oracle 数据库 XE,则只需使用 Username 和 Password 登录)。
- 单击 SQL Workshop。
- 单击 SQL Commands。
- 将以下代码复制并粘贴到 SQL 区域:
create sequence tree_temp_seq start with 1
然后单击 Run。
- 将以下代码复制并粘贴到 SQL 区域:
create table tree_temp
( temp_id number,
app_user varchar2(100),
app_session varchar2(100),
pid number,
id number,
name varchar2(100),
exp char(1),
icon varchar2(10)
)
/
然后单击 Run。
- 将以下代码复制并粘贴到 SQL 区域:
create or replace trigger tree_temp_bi
before insert on tree_temp
for each row
declare
l_temp_id number;
begin
select tree_temp_seq.nextval
into l_temp_id
from dual;
:new.temp_id := l_temp_id;
end;
/
然后单击 Run。
第 2 步:创建所需的视图
Ajax 内存树基于视图而不是表。例如:
create or replace force view tree_view
(pid, id, name)
as
select mgr pid, empno id, ename name from emp
/
所使用的视图必须只有三列并遵循下列指导原则:
- PID:节点的父 ID
- ID:节点的唯一标识符
- Name:要显示的名称
该表还必须只有一个 PID 为空的行。该节点将是树中最高级别的节点。
您在此处开发的树将使用 EMP 表。如果要使用您自己的表,请相应地调节 CREATE VIEW 过程。
从 SQL Workshop 中:
- 将 CREATE VIEW 代码复制并粘贴到 SQL 区域,然后单击 Run。
第 3 步:安装 Ajax_MEMORY_TREE 程序包
接下来,创建 Ajax_MEMORY_TREE 程序包。该程序包包含所有用于控制树的逻辑。
- 将以下代码复制并粘贴到 SQL 区域:
create or replace package ajax_memory_tree
is
procedure init;
procedure render;
procedure find_node (p_id in varchar2);
procedure process_click;
procedure contract;
procedure expand;
end ajax_memory_tree;
/
然后单击 Run。
- 将清单 1 中的代码复制并粘贴到 SQL 区域,然后单击 Run。
第 4 步:创建 Application Express 应用程序
至此已经创建了所需的数据库对象,下一步将创建 Application Express 应用程序。如果已经有一个现成的 Application Express 应用程序,则可以在其中创建 Ajax 内存树。
- 单击 Application Builder。
- 单击 Create >。
- 选择 Create Application 并单击 Next >。
- 输入应用程序的 Name(如 Ajax Memory Tree),然后单击 Next >。
- 单击 Add Page,然后单击 Next > 添加一个空白页。
- 选择 One Level of Tabs 并单击 Next >。
- 对 Copy Shared Components from Another Application 选择 No 并单击 Next >。
- 使用 Authentication Scheme、 Language 和 Use Language Preference Derived From 的默认值,然后单击 Next >。
- 选择 Theme 3,然后单击 Next >。
- 单击 Create 创建应用程序。
第 5 步:创建区域和项目
然后,创建树所需的区域和项目。Page 1(页面 1)需要三个区域:
- JavaScript & CSS
该区域将保存所需的 JavaScript 函数和一个小型的内联 CSS 或样式表定义。
- Ajax Memory Tree
该区域只调用 ajax_memory_tree.render 过程,该过程随后将在页面上呈现树。
- Current Node
这是一个简单的 SQL 报表,其中突出显示了树中选定节点的详细信息。
- 单击 1 - Page 1 编辑应用程序中的第 1 页。
- 单击 Add Region 图标创建一个新的 Region。
- 选择 HTML 并单击 Next >。
- 再次选择 HTML 并单击 Next >。
- 对 Title 输入 JavaScript and CSS,为 Region Template 选择 No Template,然后单击 Next >。
- 对于 HTML Region Text Source,复制并粘贴清单 2 中的代码,然后单击 Create Region。
此 JavaScript 包含三个用于控制树的折叠和展开的函数以及一个弹出式 Find 窗口:
- popupNodeFinder
该函数将只基于应用程序的第 2 页打开一个新的弹出窗口。
- html_TooglePlusMinus
该函数在由 getTreeNode 调用时将切换单击的 + 和 - 图标。此外,它还将 Application Express Item P1_BRANCH 设置为刚刚单击的项目的值。最后,它将异步调用某个应用程序进程(contractTree 或 expandTree),该进程随后将更新 tree_temp 表。
- getTreeNode
该函数是 Ajax 内存树的核心。每次单击树中的 + 或 - 图标时将调用该函数。该函数在执行时将首先调用 html_TogglePlusMinus,后者将更改图标设置 P1_BRANCH。然后,它将调用应用程序进程 processClick 并传入 P1_BRANCH 的值。随后,processClick 进程将调用 ajax_memory_tree.process_click 过程,该过程将呈现新展开的节点及其同类。
该区域的嵌入样式表部分用于指示当前选定的节点。选择节点后,selected_node 样式将应用于该节点,从而为其提供一个浅绿色的背景。所有其他节点使用 unselected_node 样式呈现。
接下来,创建树的区域。该区域将只包含一个针对 ajax_memory_tree package.render 过程的 PL/SQL 调用。
- 单击 Add Region 图标创建一个新的 Region。
- 选择 PL/SQL Dynamic Content 并单击 Next >。
- 对 Title 输入 Ajax Memory Tree,然后单击 Next >。
- 对于 PL/SQL Source 输入 ajax_memory_tree.render;,然后单击 Create Region。
要使树起作用,还必须向该页中添加四个项目。这些项目用于存储信息,如树的根节点、单击的节点以及树的当前节点。
- 单击 Add Item 图标创建一个新的 Item。
- 选择 Hidden 并单击 Next >。
- 对于 Item Name 输入 P1_TREE_ROOT,选择 Ajax Memory Tree 作为 Region,然后单击 Next >。
- 单击 Create Item。
- 单击 Add Item 图标创建一个新的 Item。
- 选择 Hidden 并单击 Next >。
- 对 Item Name 输入 P1_SELECTED_NODE,选择 Ajax Memory Tree 作为 Region,后单击 Next >。
- 单击 Create Item。
- 单击 Add Item 图标创建一个新的 Item。
- 选择 Hidden 并单击 Next >。
- 对 Item Name 输入 P1_MESSAGE,选择 Ajax Memory Tree 作为 Region,然后单击 Next >。
- 单击 Create Item。
- 单击 Add Item 图标创建一个新的 Item。
- 选择 Hidden 并单击 Next >。
- 对于 Item Name 输入 P1_BRANCH_ID,选择 Ajax Memory Tree 作为 Region,然后单击 Next >。
- 单击 Create Item。
- 单击 Add Item 图标创建一个新的 Item。
- 选择 Display Only 并单击 Next >。
- 选择 Display as Text (does not save state) 并单击 Next >。
- 对于 Item Name 输入 P1_FIND,选择 Ajax Memory Tree 作为 Region,然后单击 Next >。
- 对于 Label,输入:
<a href="#" onClick="popupNodeFinder ()";><img
src="/i/flashlight.gif" title="Find an Employee"></a>
- 对于 Label Template 选择 Optional,然后单击 Next >。
- 单击 Create Item。
接下来,您将需要创建一个简单的报表区域。该报表将显示树中当前选定节点中的数据。
- 单击 Add Region 图标创建一个新的 Region。
- 选择 Report 并单击 Next >。
- 选择 SQL Report 并单击 Next >。
- 输入 Current Node 作为 Title,选择 2 作为 Column,然后单击 Next >。
- 对于 SQL Query 输入:
select * from tree_view where id = :P1_SELECTED_NODE
然后单击 Create Region。
第 6 步:创建进程和分支
为简化树的导航和控制,需要创建两个页面级进程、三个应用程序级进程和一个分支。
在每个会话中,一次将只调用一个页面级进程 (Initialize the Tree)。该进程将调用 ajax_memory_tree.init 过程,用于从当前用户的 tree_temp 表中清除过时的会话信息,并设置树的根节点。
另一个页面级进程 (Find Node) 仅当在调用 Find Node 弹出窗口时执行。该进程将调用 ajax_memory_tree.find_node 过程,传入用户选择的节点。然后,它将呈现该树,突出显示指定节点并相应地展开树。
- 在 Page Rendering - Processes 下,单击 Add Process 图标添加一个新进程。
- 选择 PL/SQL 并单击 Next >。
- 输入 Initialize the Tree 作为 Name 并单击 Next >。
- 对于 Enter PL/SQL Page Process,输入: ajax_memory_tree.init;
并单击 Next >。
- 保留 Success & Failure Messages 为空并单击 Next >。
- 对于 Condition Type,选择 Value of Item in Expression 1 is NULL,对于 Expression 1 输入 P1_TREE_ROOT,然后单击 Create Process。
- 在 Page Processing - Processes 下,单击 Add Process 图标添加一个新进程。
- 选择 PL/SQL 并单击 Next >。
- 输入 Find Node 并单击 Next >。
- 对于 Enter PL/SQL Page Process,输入: ajax_memory_tree.find_node(:P1_SELECTED_NODE);
,然后单击 Next >。
- 保留 Success & Failure Messages 为空并单击 Next >。
- 对于 Condition Type,选择 Request = Expression 1,对于 Expression 1 输入 FIND_NODE,然后单击 Create Process。
为支持树的异步或 Ajax 部分,您需要创建三个应用程序级进程。这些进程将由先前添加到该页的 JavaScript 函数调用。
例如,JavaScript 函数 getTreeNode 将调用应用程序级进程 processClick,并在应用程序的 Page 0 上运行它:
htmldb_Get(null,&APP_ID.,'APPLICATION_PROCESS=processClick',0);
get.add('P1_BRANCH_ID',pValue);
gReturn = get.get();
在此处获得有关 htmldb_Get 函数的更多信息。
- 在 Breadcrumb Menu 中,单击 Application X,其中 X 是应用程序的 Application ID。
- 单击 Shared Components。
- 在 Logic 下,单击 Application Processes。
- 单击 Create >。
- 对于 Name 输入 contractTree,选择 On Demand:Run this application process when requested by a page process,然后单击 Next >。
- 对 Process Text 输入: ajax_memory_tree.contract;,然后单击 Next >。
- 单击 Create Process。
- 单击 Create >。
- 对于 Name 输入 expandTree,选择 On Demand:Run this application process when requested by a page process,然后单击 Next >。
- 对 Process Text 输入: ajax_memory_tree.expand;,然后单击 Next >。
- 单击 Create Process。
- 单击 Create >。
- 对于 Name 输入 processClick,选择 On Demand:Run this application process when requested by a page process,然后单击 Next >。
- 对 Process Text 输入: ajax_memory_tree.process_click;,然后单击 Next >。
- 单击 Create Process。
最后,您需要构建一个无条件分支。该分支无条件地将应用程序重新定向回 Page 1。
- 单击页面右上角的 Edit Page 图标编辑第 1 页。
- 单击 Add Branch 图标创建一个新的 Branch。
- 接受默认值,然后单击 Next >。
- 为 Page 输入 1,然后单击 Next >。
- 单击 Create Branch。
第 7 步:创建其他页面
Ajax 内存树的所有项目和区域均置于应用程序的第 1 页上。但为使树正常工作,还需要两个页面。
- Page 0:要使 Ajax 组件正常工作,需要创建第 0 页,该页是 Application Express 中的特殊页面。当应用程序级进程运行时,它们将在第 0 页上运行。由于第 0 页不包含逻辑,并且由于不执行任何其他业务规则,因此应用程序进程可以在该页上安全地运行。
- Search Page:为使搜索功能正常工作,还需要创建另一个标准页面。该页面可以是 Application Express 中的任何页面编号。本示例使用了第 2 页。
- 在 Page Definition 页上,单击 Create > 按钮,该按钮紧靠 Edit Attributes 按钮的右侧。
- 选择 New Page 并单击 Next >。
- 选择 Blank Page 并单击 Next >。
- 对于 Page 输入 0,然后单击 Next >。
- 对于 Name 输入 Page Zero,然后单击 Next >。
- 对于 Would you like to use tabs for this new page? 选择 No,然后单击 Next >。单击 Finish。
- 单击 Edit Page。
- 在 Page Definition 页上,单击 Create > 按钮,该按钮紧靠 Edit Attributes 按钮的右侧。
- 选择 New Page 并单击 Next >。
- 选择 Blank Page 并单击 Next >。
- 对于 Page 输入 2,然后单击 Next >。
- 对于 Name 输入 Find Node,然后单击 Next >。
- 对于 Would you like to use tabs for this new page? 选择 No,然后单击 Next >。
- 单击 Finish。
- 单击 Edit Page。
第 8 步:创建第 2 页区域
需要在第 2 页上创建两个区域:一个区域用于保存将选定节点回传至第 1 页所需的 JavaScript,另一个区域用于保存针对树中所有项目的报告。如果树包含很多项目,则可以以后自定义该报表以包含搜索功能。
- 单击 Add Region 图标在第 2 页上创建一个新的 Region。
- 选择 HTML 并单击 Next >。
- 再次选择 HTML 并单击 Next >。
- 对于 Title 输入 JavaScript,对于 Region Template 选择 No Template,然后单击 Next >。
- 对于 HTML Region Text Source,请复制并粘贴以下代码:
<script language="JavaScript">
function passBack(passVal1, passVal2)
{
opener.document.getElementById("P1_SELECTED_NODE").value = passVal1;
opener.document.getElementById("P1_MESSAGE").value = passVal2;
window.opener.doSubmit('FIND_NODE');
close();
}
</script>
然后单击 Create Region。
- 单击 Add Region 图标创建一个新的 Region。
- 选择 Report 并单击 Next >。
- 选择 SQL Report 并单击 Next >。
- 输入 Search for a Node 作为 Title,然后单击 Next >。
- 对于 SQL Query,输入:
select id, name, '[select]' pick from tree_view
然后单击 Create Region。
当用户选择一个要查看的节点时,必须调用 JavaScript 的 passBack 函数。该函数将选定 ID 回传至原始页面并提交它。它还将触发要运行的 Find Node 进程。
- 单击 Report 区域旁边的单词 Report。
- 单击相应的 Edit 图标编辑 Pick 列。
- 向下滚动到 Column Link 部分。
- 对于 Link Text 输入 #PICK#,选择 URL 作为 Target,并对 URL 输入
javascript:passBack('#ID#','The current node is now #NAME# .')
- 滚动到页面顶端,然后单击 Apply Changes。
- 再次单击 Apply Changes。
第 9 步:测试 Ajax 内存树
此时,您已经创建了 Ajax 内存树所需的所有组件。余下的操作就是测试应用程序。
- 在 Breadcrumb Menu 中,单击 Application X,其中 X 是应用程序的应用程序 ID。
- 单击 Run Application。
- 使用登录到 Application Express 时所使用的同一用户名和密码。
- 单击 + 或 - 图标展开和/或折叠每个节点。此外,单击树中的名称并验证 Current Node 报告是否已更改。
您的应用程序应如下所示:
恭喜,您已经在 Application Express 中构建了一个基于 Ajax 的树!
要获得另一个有关如何使用 Ajax 扩展 Oracle HTML DB 的简短示例,请参阅我在此处发表的网志条目。
Scott Spendolini ( scott@sumnertech.com ) 是 Sumner Technologies, LLC ( www.sumnertech.com) 的总裁和创始人,这是一家专门研究 Oracle Application Express 的咨询公司。
将您的意见发送给我们 |