Oracle APEX 5.1.3中Interactive Grid的Apex_application.G_FNN.COUNT返回0问题
解决方案:老版本APEX中验证可编辑Interactive Grid(含新增行)的列值
针对你遇到的老版本APEX无法通过APEX_APPLICATION.G_FNN获取IG提交数据、无提交前流程的问题,提供以下3种可行的当前版本解决方案:
方案1:利用IG内置验证(最简方案)
前端基础验证
直接在IG的列属性中配置前端验证规则:
- 进入IG列的编辑界面,找到「验证」分组,设置必填、格式正则、数值范围等规则。
- 该验证会在用户输入、行保存时自动触发,覆盖现有行和新增行,无需额外代码。
后端复杂验证(通过行处理)
如果需要关联数据库的复杂校验,放弃G_FNN,直接在IG的行处理中编写逻辑:
- 进入IG的「处理」属性,找到对应保存操作的行处理(如“保存交互式网格数据”)。
- 在「处理代码」中使用
:NEW.aaa、:NEW.bbb这类绑定变量直接访问当前行的列值(新增/现有行均适用),验证不通过时抛出APEX_ERROR异常:
IF :NEW.aaa IS NULL OR :NEW.bbb <= 0 THEN APEX_ERROR.RAISE_ERROR( p_message => 'aaa不能为空,且bbb必须大于0', p_display_location => APEX_ERROR.C_INLINE_IN_NOTIFICATION ); END IF;
错误会直接显示在IG的行内通知中,符合APEX原生交互逻辑。
方案2:自定义AJAX提交+前端数据收集(复杂批量校验)
放弃IG自带保存按钮,手动收集数据并做前置验证:
- 隐藏自带保存按钮:在IG工具栏属性中取消勾选「保存」按钮的显示。
- 添加自定义按钮与动态动作:
- 创建页面按钮,点击触发动态动作,执行JS代码收集所有行数据(含新增行):
var ig = apex.region("YOUR_IG_STATIC_ID").widget().interactiveGrid("getViews", "grid"); var allRows = ig.model.getRecords(); var dataToSubmit = []; allRows.forEach(function(row){ var rowData = ig.model.getRecordValues(row); dataToSubmit.push({ aaa: rowData.aaa, bbb: rowData.bbb, ccc: rowData.ccc, ddd: rowData.ddd, eee: rowData.eee, fff: rowData.fff, ggg: rowData.ggg, row_status: rowData[ig.model.STATUS_COLUMN] // 获取行状态:新增/修改/删除 }); }); // 提交到AJAX回调 apex.server.process("VALIDATE_IG_DATA", { x01: JSON.stringify(dataToSubmit) }, { success: function(res){ if(res.is_valid){ ig.save(); // 验证通过后触发IG原生保存 } else { apex.message.showErrors(res.errors); // 显示错误 } } });
- 创建AJAX回调流程:在页面「AJAX回调」中新增名为
VALIDATE_IG_DATA的流程,编写PL/SQL验证逻辑:
DECLARE l_data JSON; l_row JSON; l_errors apex_t_error; BEGIN l_data := JSON.parse(apex_application.g_x01); FOR i IN 1..l_data.get_size LOOP l_row := l_data.get(i); -- 自定义验证逻辑 IF l_row.get_string('aaa') IS NULL THEN apex_error.add_error( p_message => '第'||i||'行:aaa不能为空', p_error_type => apex_error.c_error_type_error, p_display_location => apex_error.c_inline_in_notification ); END IF; -- 其他列验证规则... END LOOP; -- 返回验证结果 apex_json.open_object; apex_json.write('is_valid', apex_error.get_first_error IS NULL); apex_json.write('errors', apex_error.get_errors); apex_json.close_object; EXCEPTION WHEN OTHERS THEN apex_json.open_object; apex_json.write('is_valid', FALSE); apex_json.write('errors', apex_t_error(apex_error.create_error(p_message => SQLERRM))); apex_json.close_object; END;
方案3:隐藏页面项传递IG数据(页面提交场景)
如果需要通过页面提交而非AJAX处理,可通过隐藏项中转数据:
- 添加隐藏页面项:创建类型为「隐藏」的页面项(如
PXX_IG_DATA)。 - 动态动作收集数据:在自定义提交按钮的点击事件中,先执行JS将IG数据转成JSON赋值给隐藏项:
var ig = apex.region("YOUR_IG_STATIC_ID").widget().interactiveGrid("getViews", "grid"); var allRows = ig.model.getRecords(); var dataToSubmit = []; allRows.forEach(function(row){ dataToSubmit.push(ig.model.getRecordValues(row)); }); apex.item("PXX_IG_DATA").setValue(JSON.stringify(dataToSubmit));
- 提交后处理验证:在页面「提交后流程」中解析隐藏项的JSON数据,执行验证:
DECLARE l_data JSON; l_row JSON; BEGIN l_data := JSON.parse(:PXX_IG_DATA); FOR i IN 1..l_data.get_size LOOP l_row := l_data.get(i); IF l_row.get_string('aaa') IS NULL THEN RAISE_APPLICATION_ERROR(-20001, '第'||i||'行:aaa不能为空'); END IF; -- 其他验证规则... END LOOP; -- 验证通过后可手动处理数据,或触发IG保存逻辑 END;
关键说明
老版本APEX中,IG的AJAX提交不会将数据放入APEX_APPLICATION.G_FNN数组,因此直接访问该变量必然为空,以上方案均绕开了这个限制,适配现有版本的IG交互逻辑。
内容的提问来源于stack exchange,提问作者No Body
相关产品推荐
相关产品推荐

