本章把 APEX 应用的页面流和会话状态放在一起理解:前者决定用户如何从一个页面进入下一个页面,后者决定临时值如何在请求、页面和用户会话之间保存、使用和清理。
8 理解页面流与会话状态 #
APEX 应用通常不是孤立页面的集合,而是一组由业务任务串起来的页面。用户通过导航菜单进入业务功能,通过导航栏访问应用选项,再通过分支、重定向、面包屑、向导进度、模态对话框和抽屉在页面之间移动。
页面流解决“用户下一步去哪里”的问题;会话状态解决“跨请求、跨页面哪些临时值仍然可用”的问题。本章用三步新员工入职向导和列表/编辑流程两条主线,把这两个概念连在一起。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 能说明导航、页面分支和会话状态在一个业务任务中的职责。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Understanding Page Flow & Session State
8.1 导航到业务功能 #
用户登录后希望看到自己可以执行的任务。Navigation Menu 列表项用于把业务功能组织成清晰入口,例如提交职位申请、录入工时卡、新员工入职、审批收件箱、查看休假余额和申请休假。
创建页面时可以让 Create Page 向导自动添加导航菜单项,也可以稍后在 Shared Components > Navigation Menu 中手工维护。菜单项只负责入口呈现和目标导航;真正的访问控制仍应交给授权方案。
图 8-1 8.1 导航到业务功能(本地捕获图像:navmenu.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 创建或检查一个导航菜单项,运行应用后确认点击入口能进入对应业务页面。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Navigating to Business Functions
8.2 导航栏中的应用选项 #
Navigation Bar List 通常承载用户名下拉菜单中的应用级操作,例如 Settings、About this Application、Push Notification 和 Sign Out。Create Application 向导默认创建 Sign Out 条目,其他功能也可能自动补充相关入口。
可以把导航菜单理解为“业务任务入口”,把导航栏理解为“当前用户或应用级选项入口”。这种分工能让用户快速判断一个链接是开始业务操作,还是管理应用/账号状态。
图 8-2 8.2 导航栏中的应用选项(本地捕获图像:navbarlist.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 在 Shared Components > Navigation Bar List 中查看 Sign Out 等条目,并确认它们显示在用户菜单中。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:App Options in the Navigation Bar
8.3 配置向导页面流 #
Wizard 是把复杂任务拆成多个有序步骤的 UI 模式。新员工入职示例把身份信息、岗位信息和薪酬信息拆成三个页面,用户可以前进、后退、取消,最后在 Finish 步骤确认完成。
APEX 向导页面流由多页、向导进度列表、页面按钮和分支组成。页面收集当前步骤的数据,共享列表定义步骤标题和顺序,分支把 Next、Previous、Finish 等按钮连接到目标页面。
图 8-3 8.3 配置向导页面流(本地捕获图像:wizard.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 能画出一个三步向导中页面、按钮、共享列表和分支的关系。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Configuring a Wizard Page Flow
8.3.1 创建多步骤向导 #
Create Page 向导可以自动生成多页向导。官方示例创建 Onboard New Employee,包含第 43、44、45 页。每页都有向导进度区域、当前步骤页面项以及 Next、Previous、Finish、Cancel 等按钮。
创建向导时需要指定向导名称、步骤标签、页面编号和导航图标。创建完成后,APEX 打开第一页的 Page Designer,后续再由开发者为每个步骤补充具体页面项和业务处理。
图 8-4 8.3.1 创建多步骤向导(本地捕获图像:wizard-container-template.png)。
图 8-5 8.3.1 创建多步骤向导(本地捕获图像:wizard-create.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 用 Create Page > Wizard 生成三页向导,并确认页面、按钮和进度列表都已创建。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Creating a Multi-Step Wizard
8.3.2 在 Page Designer 中编辑多步骤向导 #
向导生成初始页面后,需要在 Page Designer 中添加每一步的具体内容。示例第 44 页 Job Role 区域是 List region,使用 Wizard Container 模板选项和 Wizard Progress 列表模板显示步骤进度。
Previous、Close、Next 等按钮放在 Wizard Container 模板的槽位中。共享 List 组件提供步骤条目,页面区域负责把这些条目渲染为“列车站点”式进度。
图 8-6 8.3.2 在 Page Designer 中编辑多步骤向导(本地捕获图像:wizard-page-designer.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 选中向导 List region,检查 List、Template、Template Options 和按钮槽位。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Multi-Step Wizard in Page Designer
8.3.3 共享列表定义向导页面 #
向导步骤标题和顺序来自 Shared Components 中的 List。Onboard New Employee 列表包含第 43、44、45 页三个条目,List region 再用 Wizard Progress 模板显示为步骤进度。
这种结构让步骤定义集中维护。修改共享列表中的条目标签或顺序后,所有使用该列表的向导页面都会体现变化。
图 8-7 8.3.3 共享列表定义向导页面(本地捕获图像:add-new-emp-wizard-list.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 在 Shared Components > Lists 中修改一个步骤标题,运行向导确认进度条同步变化。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Shared List Defines Wizard Pages
8.3.4 用分支连接页面以定义流程 #
Branch 定义页面提交处理后应该导航到哪里。Page Designer 的 Processing 选项卡中可以创建分支,指定目标页面、传递参数,并通过 When Button Pressed 限定哪个按钮触发该分支。
示例中第 43 页 Next 指向第 44 页;第 44 页 Previous 指回第 43 页、Next 指向第 45 页;第 45 页 Previous 指回第 44 页、Finish 指向首页。Cancel 通常配置为重定向,不提交当前页面数据。
图 8-8 8.3.4 用分支连接页面以定义流程(本地捕获图像:wizard-three-pages.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 检查每页 Branch 的 Target 和 When Button Pressed,确认每个按钮只触发预期分支。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Branches Link Pages to Define Flows
8.3.5 呈现、提交、分支、重复 #
APEX 运行时根据页面和组件定义执行一个稳定循环:渲染页面、接收提交、运行计算/验证/处理、执行分支,然后渲染下一个页面。
理解这个生命周期后,才能判断逻辑应放在 Pre-Rendering、Validating、After Submit、Processing、Branches 还是 Dynamic Actions 中。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 能把一次按钮点击对应到 APEX 生命周期中的具体阶段。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Render, Submit, Branch, Repeat
8.3.5.1 向导示例的页面生命周期 #
用户点击 Onboard New Employee 导航项后,APEX 根据第 43 页定义渲染页面。渲染前会先执行 Rendering 选项卡 Pre-Rendering 阶段的计算和处理,然后把区域、模板、页面项、按钮、CSS 和 JavaScript 输出到浏览器。
用户输入身份信息并点击 Next 后,浏览器提交页面项值。APEX 按 Processing 选项卡中的顺序执行计算、验证、处理和分支,第 43 页的 Next 分支决定第 44 页显示为下一页。
图 8-9 8.3.5.1 向导示例的页面生命周期(本地捕获图像:render-submit-branch.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 启用 Debug 后点击 Next,查看调试日志中的验证、处理和分支顺序。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Wizard Example Page Lifecycle
8.3.5.2 在呈现或提交阶段计算值 #
Computation 用于设置页面项或应用项。如果计算结果影响页面初始显示,应放在 Pre-Rendering 阶段;如果用于提交后的保存前处理,应放在 Processing 选项卡的 After Submit 阶段。
计算来源可以是静态值、另一个项的值、PL/SQL 表达式、单列 SQL 查询或用户偏好。多值项可把多行查询结果格式化为分隔值或 JSON Array。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 分别创建渲染前计算和提交后计算,观察它们影响页面值的时机。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Computing Values on Render or Submit
8.3.5.3 验证提交的数据 #
Validation 在保存前检查提交数据的正确性,位于 Processing 选项卡的 Validating 执行点。它可以检查单个页面项,也可以用声明式条件、PL/SQL、SQL 或系统记录表检查复杂规则。
如果任何验证失败,用户会看到配置的错误消息,APEX 不会执行 Submit 生命周期后续 Processing 阶段的处理。Interactive Grid 列验证需要设置 Editable Region 并按列名引用网格列。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 创建一个必填或业务规则验证,确认非法输入会阻止保存处理执行。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Validating Submitted Data
8.3.5.4 在呈现或提交阶段执行自定义处理 #
Page Process 可以放在 Rendering 的 Pre-Rendering 阶段,也可以放在 Processing 的 After Submit 或 Processing 阶段。Execute Code 处理类型适合写应用特有逻辑,原生处理类型适合工作流、邮件、通知、报表打印、数据装载、API 调用、用户偏好和表单/网格保存等常见任务。
官方示例在向导最后一页创建 Execute Code 处理,并把 When Button Pressed 设为 FINISH,只有用户确认完成时才把第 43、44、45 页收集的数据插入 EMP 表。
insert into emp(empno, ename, deptno, hiredate, job, sal, comm)
values (:P43_EMPNO, :P43_ENAME, :P44_DEPTNO,
apex_session_state.get_timestamp('P44_HIREDATE'),
:P45_JOB, :P45_SAL, :P45_COMM);
图 8-10 8.3.5.4 在呈现或提交阶段执行自定义处理(本地捕获图像:page-process-insert-emp.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 创建 FINISH 按钮专用页面处理,确认点击 Previous 时不会执行插入逻辑。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Custom Processing on Render or Submit
8.3.5.5 Invoke API 最佳实践 #
Oracle 建议把大部分业务逻辑写在 PL/SQL 包过程和函数中,再从页面中调用。Invoke API 页面处理可以声明式调用包过程,Page Designer 会显示过程参数,并在可能时自动把同名页面项映射为参数值。
这样做比在页面中散落大量内联 PL/SQL 更容易测试、复用和维护。低代码开发者可以配置页面调用,由资深开发者维护数据库包中的业务服务。
create or replace package body hr_app as
procedure add_new_employee(
p_empno in emp.empno%type,
p_ename in emp.ename%type,
p_deptno in emp.deptno%type,
p_hiredate in emp.hiredate%type,
p_job in emp.job%type,
p_sal in emp.sal%type,
p_comm in emp.comm%type) is
begin
insert into emp(empno, ename, deptno, hiredate, job, sal, comm)
values (p_empno, p_ename, p_deptno, p_hiredate, p_job, p_sal, p_comm);
end add_new_employee;
end hr_app;
图 8-11 8.3.5.5 Invoke API 最佳实践(本地捕获图像:page-process-invoke-api.png)。
图 8-12 8.3.5.5 Invoke API 最佳实践(本地捕获图像:page-process-invoke-api-param.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 把内联 INSERT 迁移到 HR_APP.ADD_NEW_EMPLOYEE,并用 Invoke API 配置参数映射。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Best Practice Use of Invoke API
8.3.5.6 让几乎任何元素具备条件 #
几乎所有 APEX 页面元素都可配置 Server-side Condition,包括区域、页面项、列、按钮、验证、计算、处理和分支。条件为真时,元素才会渲染或执行。
按钮提交时,APEX 会把 REQUEST 设置为按钮名称。多个按钮共享逻辑时,可以使用 Request is contained in value,或用 PL/SQL 表达式精确列出允许的按钮名,避免 SAVE 与 SAVE_ADDRESS 这类包含关系导致误匹配。
:REQUEST in ('SAVE','UPDATE','INCREMENT')
:REQUEST in ('SAVE_ADDRESS','SAVE_ASSIGNMENT')
/* SAVE alone does not match */
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 给处理添加 :REQUEST in (...) 条件,确认只有指定按钮触发。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Making Almost Any Element Conditional
8.4 其他页面流功能 #
除了整页呈现、提交和分支,APEX 还支持后台数据请求、局部刷新和不提交数据的重定向。Breadcrumb 帮助用户理解钻取路径,Modal Dialog 和 Drawer 则能在保留调用页上下文的同时处理相关信息。
这些能力的共同目标是让页面流更自然:能局部刷新时不整页刷新,能保留上下文时不强制用户离开当前页面,能显示层级路径时不让用户迷路。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 能判断一个交互应使用 AJAX、Redirect、Breadcrumb 还是 Modal Dialog。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Additional Page Flow Features
8.4.1 理解 AJAX 与重定向 #
AJAX 请求让页面在后台与服务器交换数据,不刷新整页。APEX 常见 AJAX 场景包括 Execute Server-side Code 动态操作和 Refresh 区域刷新;Items to Submit、Items to Return 和 Page Items to Submit 决定请求携带和返回哪些值。
Redirect 是导航到另一个 URL,可传递参数,但不会提交当前页面改动,因此不会更新当前页面项的会话状态。若存在未保存更改,APEX 默认会给出警告,可通过 Warn on Unsaved Changes 控制。
图 8-13 8.4.1 理解 AJAX 与重定向(本地捕获图像:ajax-and-redirect.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 用 Refresh 动态操作刷新报表,再用 Redirect 跳转页面,比较地址栏和会话状态变化。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Understanding AJAX and Redirect
8.4.2 用面包屑可视化钻取路径 #
用户从列表钻取到明细,再进入相关记录时,Breadcrumb 可以显示当前所在层级并提供返回路径。官方示例从 Manage Employees 报表页进入 Employee 表单页,再进入 Dependents 列表页,最后进入 Dependent 表单页。
Breadcrumb 条目的短名称可使用页面项替换字符串,例如 &P6_ENAME. 或 &P9_NAME.。为了在后续页面继续显示正确名称,相关页面项需要使用 Per Session (Persistent) 存储,例如 P6_ENAME 和 P6_EMPNO。
图 8-14 8.4.2 用面包屑可视化钻取路径(本地捕获图像:emp-and-dependents.png)。
图 8-15 8.4.2 用面包屑可视化钻取路径(本地捕获图像:multilevel-drilldown-flow.png)。
图 8-16 8.4.2 用面包屑可视化钻取路径(本地捕获图像:define-breadcrumbs.png)。
图 8-17 8.4.2 用面包屑可视化钻取路径(本地捕获图像:manage-emps-1.png)。
图 8-18 8.4.2 用面包屑可视化钻取路径(本地捕获图像:manage-emps-2.png)。
图 8-19 8.4.2 用面包屑可视化钻取路径(本地捕获图像:manage-emps-3.png)。
图 8-20 8.4.2 用面包屑可视化钻取路径(本地捕获图像:manage-emps-4.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 为主从钻取页面配置面包屑层级,并确认返回链接和当前对象名称都正确显示。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Breadcrumbs Visualize Drilldown Path
8.4.3 模态对话框与抽屉 #
Modal Dialog 页面显示在调用页上方,打开时用户不能操作底层页面;关闭或取消后,调用页恢复活动。若 Dialog Template 设为 Drawer,同一模态页面会从窗口边缘滑出,并占据窗口全高。
关闭对话框可以使用 Close Dialog 动态操作或 Close Dialog 页面处理,并可返回页面项值给调用页。调用页可监听 Dialog Closed 事件,读取返回项并刷新相关区域。Chained 属性决定模态页面再打开模态页面时复用窗口还是叠加窗口。
图 8-21 8.4.3 模态对话框与抽屉(本地捕获图像:modal-dialog.png)。
图 8-22 8.4.3 模态对话框与抽屉(本地捕获图像:modal-drawer.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 把编辑页分别设为 Modal Dialog 和 Drawer,比较两种方式对父页面上下文的保留。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Modal Dialogs and Drawers
8.5 理解会话状态管理 #
有些提交会立即保存到业务表;另一些场景则需要先临时保存,等用户完成流程后再统一落库。APEX 把每个用户会话中的页面项、应用项、集合和上传文件等临时值统称为 session state。
理解会话状态的关键是生命周期:值属于哪个用户会话,在哪个请求中产生,是否跨页面保留,何时清理,最终是否需要写入系统记录表。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 能区分浏览器输入框中的值、服务器 session state 中的值和业务表中的值。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Understanding Session State Management
8.5.1 临时存储的使用场景 #
临时存储常用于四类场景:多页面任务、查询示例搜索、临时数据集合和文件上传。多页面任务需要让用户输入跨步骤保留;搜索条件常需要在会话内保持粘性;购物车等集合在结账前只是临时数据;上传附件在业务流程完成前通常先保存在临时区。
这些值不应全部直接写入业务表。应先判断它们是当前请求临时值、当前会话临时值、跨会话用户偏好,还是已经确认的业务事实。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 为一个业务流程标注哪些值用页面项、集合、临时文件或业务表保存。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Use Cases for Temporary Storage
8.5.2 临时值的会话上下文 #
用户会话从用户访问并登录应用开始,到退出或空闲超时结束。同一时间可能有多个用户使用同一应用,APEX 为每个用户分配唯一 session ID。
这个 session ID 为用户交互和 session state 提供隔离上下文。两个用户使用同名页面项,也只能看到各自会话中的值。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 用两个浏览器窗口登录同一应用,确认同名页面项值按会话隔离。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Session Context for Temporary Values
8.5.3 APEX 如何管理用户会话状态 #
三页入职向导要求用户在 Next 和 Previous 之间不丢失输入,但只有点击 Finish 时才插入 EMP 表。做法是把需要跨步骤保留的页面项设置为 Per Session (Persistent)。
页面渲染时,APEX 使用 session state 中的持久页面项值;页面提交完成后,它保存当前页中 Per Session 项的值,再执行分支或重新渲染。Per Request (Memory Only) 项则在请求结束后被忘记,除非处理过程保存或通过参数传递。
图 8-23 8.5.3 APEX 如何管理用户会话状态(本地捕获图像:session-state-render-submit-branch.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 把向导页面项设为 Per Session,来回切换步骤后确认输入仍在。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:How APEX Manages User Session State
8.5.4 用户特定的临时存储 #
若页面项值需要跨多个会话保留,可把 Session State > Storage 设为 Per User (Persistent)。这适合查询示例条件、用户选项等希望下次访问仍保持的偏好。
APEX_UTIL 包也提供 SET_PREFERENCE 和 GET_PREFERENCE,但对页面项而言,直接使用 Per User (Persistent) 是更简单的声明式方式。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 把搜索页面项设为 Per User,退出再登录后确认同一用户仍保留上次条件。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:User-Specific Temporary Storage
8.5.5 清除会话状态 #
会话结束时,APEX 会清理页面项、集合和临时文件等 session state;结束方式包括用户退出和空闲超时。会话期间也可以声明式清理指定状态。
常见方法有两种:在目标链接的 Clear Cache 中列出页面或集合,或在提交处理结束时使用 Clear Session State 页面处理。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 能说明什么时候应在进入页面前清理,什么时候应在成功处理后清理。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Clearing Session State
8.5.5.1 用链接目标设置清除状态 #
定义指向页面的链接时,可以在 Clear Cache 中列出一个或多个页面编号,清除这些页面的 session state。官方示例把 Onboard New Employee 菜单项设为 43,44,45,保证每次开始新向导都是干净状态。
Clear Cache 还可列出集合名称,或使用 RP 清除相关页面的报表分页。相同设置也可在按钮或链接的 Link Builder 对话框中配置。
图 8-24 8.5.5.1 用链接目标设置清除状态(本地捕获图像:link-target-settings.png)。
图 8-25 8.5.5.1 用链接目标设置清除状态(本地捕获图像:link-target-settings-button.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 在向导入口的 Clear Cache 中填写页号列表,确认重新进入时没有旧输入。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Clearing State with Link Target Settings
8.5.5.2 用页面处理清除状态 #
若需要在提交成功后再清理状态,可以使用 Clear Session State 原生页面处理。官方示例在向导最后一页配置该处理,FINISH 按钮成功插入新员工后清除第 43、44、45 页的页面项状态。
这种方式比进入页面前清理更适合“成功才清除”的流程,因为保存失败时用户仍可修正输入并重试。
图 8-26 8.5.5.2 用页面处理清除状态(本地捕获图像:clear-session-state-proc.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 把 Clear Session State 排在保存处理之后,并限制为 FINISH 按钮触发。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Clearing State with a Page Process
8.5.6 应用项 #
Application Item 是在用户会话期间保持的命名值。典型用法是 USER_ID:用户用用户名登录,但业务表引用 USERS.ID,因此可在认证后计算 USER_ID,避免各页面重复按用户名查询主键。
应用项可在不同上下文中用 #USER_ID#、&USER_ID. 或 :USER_ID 引用。PL/SQL 也可以调用 APEX_SESSION_STATE.SET_VALUE 设置它的值。
select id
from users
where username = lower(:APP_USER)
图 8-27 8.5.6 应用项(本地捕获图像:app-computation.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 创建 USER_ID 应用项和 After Authentication 应用计算,登录后在 session state 中确认值。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Application Items
8.5.7 使用临时集合 #
APEX Collection 允许在当前用户会话中存储一组临时行。运行时通过 APEX_COLLECTION 包创建命名集合;一个会话可以有多个集合,会话结束时 APEX 自动清理。
集合适合购物车、向导暂存、批量上传预览和复杂页面编辑等场景。它不是长期业务表,流程完成后应把确认数据写入正式表。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 能判断购物车、上传预览或批量编辑是否适合先用集合承载。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Using Temporary Collections
8.5.7.1 集合关键概念 #
集合不需要预先定义结构,而是使用固定通用列:c001-c050 存 VARCHAR2,n001-n005 存 NUMBER,d001-d005 存 DATE,另有 clob001、blob001 和 xmltype001。每个成员都有 SEQ_ID,可用于更新或删除。
查询集合时使用 APEX_COLLECTIONS 视图,并以 collection_name 过滤。APEX 会按会话隔离集合数据,因此同名集合在不同用户会话中互不干扰。
数据类型 列名 数量 VARCHAR2 c001-c050 50 NUMBER n001-n005 5 DATE d001-d005 5 CLOB clob001 1 BLOB blob001 1 XMLTYPE xmltype001 1
apex_collection.create_collection(p_collection_name => 'SHOPPING_CART');
apex_collection.add_member(
p_collection_name => 'SHOPPING_CART',
p_c001 => 'COMP-APPL-MBP-16',
p_n001 => 2,
p_d001 => date'2025-05-27');
select c001 as item_code,
n001 as quantity,
d001 as need_by_date
from apex_collections
where collection_name = 'SHOPPING_CART';
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 创建 SHOPPING_CART 集合,写入商品编号、数量和需要日期,再用 APEX_COLLECTIONS 查询。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Key Collections Concepts
8.5.7.2 可维护集合使用建议 #
为了让页面不直接依赖 c001、n001 这类通用列名,可以为集合查询创建视图,把列映射为 item_code、quantity、need_by_date 等业务名称。
更进一步,可以用 PL/SQL 包封装集合操作,例如 clear_cart、add_item、remove_item、update_item。页面调用业务 API,包内部负责确保集合存在、生成稳定 ID,并使用 APEX_COLLECTION 添加、删除和更新成员。
create view shopping_cart_v as
select c001 as item_code,
c002 as id,
n001 as quantity,
d001 as need_by_date
from apex_collections
where collection_name = 'SHOPPING_CART';
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 创建 shopping_cart_v 视图或 shopping_cart_api 包,让页面不直接暴露集合列实现。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Tips for Maintainable Collection Use
8.5.8 临时文件 #
File Upload 和 Image Upload 页面项都可把 Storage Type 设为 Table APEX_APPLICATION_TEMP_FILES。若 Purge File at 为 End of Session,上传文件会在当前会话期间保存在 APEX_APPLICATION_TEMP_FILES 表中。
NAME 列唯一标识临时文件,不同于用户上传的 FILENAME。单文件项可直接按页面项值查询;多文件项的值是冒号分隔的 NAME 列表,需要拆分后查询。
select blob_content, mime_type, filename
from apex_application_temp_files
where name = :P1_SINGLE_FILE_UPLOAD;
select blob_content, mime_type, filename
from apex_application_temp_files
where name in (
select column_value
from apex_string.split(:P1_MULTI_FILE_UPLOAD, ':')
);
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 上传单文件和多文件,分别查询 APEX_APPLICATION_TEMP_FILES,并确认 NAME 与 FILENAME 的区别。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Temporary Files
8.5.9 检查会话状态以调试 #
从 App Builder 运行应用时,Developer Toolbar 提供 Session > View Session State。打开后可以查看当前用户会话中的页面项、应用项、集合和后台执行。
这是排查“值为什么为空”“为什么旧值还在”“为什么当前页面上下文不对”的首选入口。调试时应看服务器端 session state,而不是只看浏览器输入框。
图 8-28 8.5.9 检查会话状态以调试(本地捕获图像:session-state-browse-pageitems.png)。
图 8-29 8.5.9 检查会话状态以调试(本地捕获图像:session-state-browse-others.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 提交页面后打开 View Session State,确认页面项、应用项或集合是否真的进入服务器端会话状态。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Inspecting Session State for Debugging
8.6 研究列表与编辑流程 #
Create Page 向导可为任意数据源快速生成列表页和编辑页。理解生成结果如何协同,有助于后续定制,也有助于从空白页手工构建同类模式。
核心结构是:列表页负责查找和选择行,编辑页负责查看、创建、更新或删除行,二者通过链接参数、表单初始化、DML 处理和对话框关闭事件连接。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 能描述“列表页链接主键到表单页,表单页按主键取数并保存,关闭后刷新列表”的完整流程。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Studying a List and Edit Flow
8.6.1 创建列表页与编辑页 #
Interactive Report 的 Create Page 流程提供 Include Form Page 开关。启用后,向导会创建一个列表页和一个配套表单页。官方示例创建 Manage Employees 报表第 3 页,同时生成 Employee 表单第 4 页。
默认 Form Page Mode 是 Modal Drawer,从侧边滑出覆盖在列表页上。创建时还可配置 Breadcrumb、导航菜单条目和 fa-users-alt 图标,并确认 EMPNO 为主键。
图 8-30 8.6.1 创建列表页与编辑页(本地捕获图像:ir-and-page-wiz.png)。
图 8-31 8.6.1 创建列表页与编辑页(本地捕获图像:ir-and-page-wiz-nav.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 用 EMP 表生成 Interactive Report 加 Form Page,确认两个页面和导航入口都已创建。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Creating List and Edit Pages
8.6.2 运行列表页与编辑页 #
运行应用后,导航菜单出现 Manage Employees 条目。进入页面后,Interactive Report 显示员工列表和 Create 按钮;从 App Builder 运行时,Developer Toolbar 也会显示在页面底部。
点击某行编辑图标后,模态抽屉从右侧滑出,允许编辑或删除所选员工。Developer Toolbar 可启用 Auto Hide,让工具栏平时更少遮挡页面。
图 8-32 8.6.2 运行列表页与编辑页(本地捕获图像:ir-and-page-wiz-nav-menu.png)。
图 8-33 8.6.2 运行列表页与编辑页(本地捕获图像:ir-page-create.png)。
图 8-34 8.6.2 运行列表页与编辑页(本地捕获图像:ir-and-drawer-runtime.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 运行 Manage Employees,搜索员工并点击编辑图标,确认抽屉显示所选记录。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Running the List and Edit Pages
8.6.3 链接到编辑页 #
向导把 Interactive Report 的 Link Column 配置为 Link to Custom Target,目标是新建表单页第 4 页。在 Set Items 中,目标页主键项 P4_EMPNO 接收当前报表行的 #EMPNO# 值。
Link Icon 使用 Font APEX 图标 HTML,并通过 aria-label 和 title 支持可访问性与悬停提示。点击图标后,用户被重定向到模态抽屉页,并把当前 EMP 行主键传给表单页。
图 8-35 8.6.3 链接到编辑页(本地捕获图像:ir-and-page-wiz-edit-link-column.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 打开 Link Builder,确认 P4_EMPNO 的值来自当前行 #EMPNO#。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Linking to the Edit Page
8.6.4 按主键取回已有行 #
表单页在 Pre-Rendering 的 Before Header 阶段有 Form - Initialization 页面处理,用于按主键取回要编辑的行。该处理通过关联 Form Region 识别数据源和主键列。
如果 P4_EMPNO 在页面渲染时有值,初始化处理会查询 EMP 并填充表单项;如果主键为空,则不查询,表单保持空白,适合新增记录。
select ename, mgr, hiredate, sal, comm, deptno
into :P4_ENAME, :P4_MGR, :P4_HIREDATE, :P4_SAL, :P4_COMM, :P4_DEPTNO
from emp
where empno = :P4_EMPNO;
图 8-36 8.6.4 按主键取回已有行(本地捕获图像:form-init.png)。
图 8-37 8.6.4 按主键取回已有行(本地捕获图像:form-table-source.png)。
图 8-38 8.6.4 按主键取回已有行(本地捕获图像:form-primary-key-col.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 分别从编辑链接和 Create 按钮打开表单,确认有主键时加载数据、无主键时为空。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Retrieving Existing Row by Primary Key
8.6.5 表单页面项使用 Memory Only 存储 #
向导生成的表单区域页面项默认使用 Per Request (Memory Only)。请求处理结束后,APEX 不会把这些值保存在用户 session state 中。
这是合理的,因为表单提交会立即通过 DML 处理保存到 EMP 表;关闭对话框后,不需要让这些字段继续留在 session state。Create 按钮不传 P4_EMPNO,因此新增表单打开时为空。
图 8-39 8.6.5 表单页面项使用 Memory Only 存储(本地捕获图像:form-all-memory-only.png)。
图 8-40 8.6.5 表单页面项使用 Memory Only 存储(本地捕获图像:list-page-create-no-params.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 确认 Create 按钮不传主键,表单项使用 Memory Only,新增时页面为空。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Memory Only Storage for Form Page Items
8.6.6 用页面处理保存更改 #
表单页生成的 Process form Employee 使用 Form - Automatic Row Processing (DML)。提交按钮的 Database Action 决定执行 INSERT、UPDATE 或 DELETE;如果按钮没有 Database Action,该处理不执行 DML。
该处理关联表单区域,默认支持对区域源执行 DML、防止丢失更新、锁定被更新或删除的行,并在插入后把主键返回到对应页面项。
图 8-41 8.6.6 用页面处理保存更改(本地捕获图像:form-dml-proc.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 检查 CREATE、SAVE、DELETE 按钮的 Database Action,并确认自动 DML 处理关联正确表单区域。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Saving Changes with a Page Process
8.6.7 条件化数据库动作按钮 #
向导会为 CREATE、SAVE、DELETE、CANCEL 配置不同运行时行为。CREATE 在 P4_EMPNO 为空时显示并执行 INSERT;SAVE 和 DELETE 在 P4_EMPNO 非空时显示,分别执行 UPDATE 和 DELETE;CANCEL 通常使用动态操作关闭对话框。
DELETE 按钮会显示确认消息并使用 Danger 样式。消息可使用 &APP_TEXT$DELETE_MSG!RAW. 这样的可翻译文本键,!RAW 允许消息包含 HTML。普通编辑页中的 Cancel 也可能通过 CANCEL 分支返回列表页。
按钮 行为 执行验证 DB Action 服务器端条件 CREATE Submit Page Yes INSERT P4_EMPNO is null SAVE Submit Page Yes UPDATE P4_EMPNO is not null DELETE Submit Page No DELETE P4_EMPNO is not null CANCEL Dynamic Action No
图 8-42 8.6.7 条件化数据库动作按钮(本地捕获图像:form-delete-button.png)。
图 8-43 8.6.7 条件化数据库动作按钮(本地捕获图像:form-cancel-button.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 从新增和编辑入口分别打开表单,确认按钮显隐和 Database Action 符合当前模式。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Conditional Database Action Buttons
8.6.8 对话框关闭后刷新列表 #
表单页 DML 处理之后,向导会配置 Close Dialog 页面处理。因为 Create、Apply Changes 和 Delete 都应关闭对话框,所以该处理通常用 REQUEST 条件限定 CREATE、SAVE 或 DELETE。
对话框关闭意味着父列表中的数据可能已变化。向导会在列表页创建 Dialog Closed 动态操作,监听由 Manage Employees 区域打开的对话框关闭事件,然后执行 Refresh 动态操作刷新 Interactive Report 区域。
图 8-44 8.6.8 对话框关闭后刷新列表(本地捕获图像:form-close-dialog-proc.png)。
图 8-45 8.6.8 对话框关闭后刷新列表(本地捕获图像:list-page-dialog-closed.png)。
图 8-46 8.6.8 对话框关闭后刷新列表(本地捕获图像:list-page-refresh-ir.png)。
✓
学习验证
前提: 拥有可运行或可检查的 APEX 26.1 应用。
APEX 区域: 与本节相关的 Page Designer、Shared Components、运行时页面或 Developer Toolbar。
操作: 保存或删除表单记录后关闭抽屉,确认父报表局部刷新并显示最新数据。
检查点: 实际页面行为与本节描述一致。
预期结果: 能把官方概念对应到自己的 APEX 页面配置和运行时效果。
来源页面:Refreshing List On Dialog Close