You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle APEX:如何通过Ajax从后端更新交互式网格并执行DML操作

问题

我用两个Interactive Grid展示数据,想要同时实现两个需求:一是正常展示数据,二是通过后端Ajax对选中的网格行执行DML操作。之前用SQL和PL/SQL尝试实现,但没达到预期效果。我写的JavaScript代码如下:

function setCellsToReadOnly () { 
    var grid   = apex.region("readonly_emp_ig_id").widget().interactiveGrid("getViews","grid");
    var model  = grid.model;
    var recordVal;

    model.forEach(function(record, index, id) { 
         
        // getFieldKey返回字段名对应的索引,用于访问记录的该字段
        recordVal = record[model.getFieldKey("VALIDATED")];  
        var meta   = model.getRecordMetadata(id);
        var fields = meta.fields;

        if (!fields) {
            fields = meta.fields = {};
        }

        if (!fields["EMPNO"] || !fields["JOB"] || !fields["MGR"] || !fields["ENAME"] ) {
            fields["EMPNO"] = {}; 
            fields["JOB"] = {}; 
            fields["MGR"] = {}; 
            fields["ENAME"] = {}; 
        }

        // 获取recordVal的第一个键对应的值
        if (recordVal[Object.keys(recordVal)[0]] === 'Y') {
            // 设置为只读
            fields["EMPNO"].ck = 1; 
            fields["JOB"].ck = 1;  
            fields["MGR"].ck = 1; 
            fields["ENAME"].ck = 1;   
            
            // 触发元数据变更
            model.metadataChanged(id); 
        } else  {
            fields["EMPNO"].ck = ""; 
            fields["JOB"].ck = "";  
            fields["MGR"].ck = ""; 
            fields["ENAME"].ck = "";  

            model.metadataChanged(id); 
        }
    });     
}
解决思路与调整方案

1. 修正只读逻辑的潜在问题

原代码中通过Object.keys(recordVal)[0]取值的方式不可靠,因为对象键的顺序不固定。APEX IG提供了更安全的字段值获取方法model.getValue(record, 字段名),建议替换:

// 替换原recordVal相关代码
var validatedVal = model.getValue(record, "VALIDATED");
// 直接判断值即可
if (validatedVal === 'Y') {
    // 设置只读逻辑不变
}

另外,设置只读属性时,官方更推荐使用fields[字段名].readonly = true而非ck=1,兼容性更好:

fields["EMPNO"].readonly = true;
fields["JOB"].readonly = true;
// ...其他字段同理

2. 实现选中行的后端Ajax DML操作

要完成选中行的DML处理,按以下步骤操作:

  • 获取选中行:通过IG的API获取选中记录
    var grid = apex.region("readonly_emp_ig_id").widget().interactiveGrid("getViews","grid");
    var model = grid.model;
    var selectedRecords = grid.getSelectedRecords();
    
  • 提取主键信息:从选中记录中取出需要传递给后端的主键(比如EMPNO)
    var selectedEmpIds = selectedRecords.map(function(record) {
        return model.getValue(record, "EMPNO");
    });
    
  • 调用后端Ajax过程:使用APEX自带的apex.server.process提交请求,传递选中的主键列表
    apex.server.process("PROCESS_SELECTED_EMP", {
        // x01为自定义参数,后端可通过apex_application.g_x01获取
        x01: JSON.stringify(selectedEmpIds)
    }, {
        success: function(response) {
            // 操作成功后刷新IG,更新数据
            apex.region("readonly_emp_ig_id").refresh();
            apex.message.showSuccess("操作完成");
        },
        error: function(xhr) {
            apex.message.showErrors([{
                type: "error",
                message: "操作失败,请重试"
            }]);
        }
    });
    
  • 后端PL/SQL处理:创建名为PROCESS_SELECTED_EMP的Ajax回调过程,解析传入的JSON参数并执行DML
    PROCEDURE process_selected_emp IS
        l_emp_ids apex_t_varchar2;
    BEGIN
        l_emp_ids := apex_string.split(json_value(apex_application.g_x01, '$'), ',');
        -- 示例:执行删除操作,根据实际需求替换为INSERT/UPDATE
        DELETE FROM emp WHERE empno IN (SELECT column_value FROM TABLE(l_emp_ids));
        COMMIT;
    EXCEPTION
        WHEN OTHERS THEN
            apex_error.raise_error(p_message => '处理失败:' || SQLERRM);
    END;
    

3. 确保函数正确触发

将setCellsToReadOnly函数绑定到IG的初始化事件上,可通过页面的动态动作实现:

  • 新建动态动作,事件选择“页面加载完成”或“Interactive Grid - 初始化后”
  • 动作选择“执行JavaScript代码”,调用setCellsToReadOnly();

内容的提问来源于stack exchange,提问作者Rao Atif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 16:24:51