1

我有一个带有自定义按钮的交互式网格。单击该按钮时,将处理选定的行:

循环遍历所有选定的行并在行满足条件时为每一行执行回调。

apex.server.process
 ("process_selected_callback"
    ,{x01:$my_id}
    ,{type:'GET', dataType: 'text', success: function( text) {}}
 );  

我的回调基本上包含以下内容:

DECLARE
    l_my_id NUMBER;

BEGIN 
    l_my_id := TO_NUMBER(apex_application.g_x01);

    package1.my_process_record(l_my_id);
                    
END;

满足行条件时的每次循环迭代,在执行回调之前,都会增加一个页面项以获取处理的记录数。在循环结束时,我调用 apex.submit:

 apex.submit('DISPLAY_SUCCESS');

调用获取包含已处理记录计数的页面项的进程 -P1_RECORDS_PROCESSED并用于apex_application.g_print_success_message向用户显示消息,说明已处理的记录数。

一切正常,但有一个问题 - 很多时候DISPLAY_SUCCESS进程在回调之前执行,因此处理的记录计数仅在显示消息后才会增加。如何确保在提交页面之前完成回调?

也许有更好的方法来处理选定的行?

4

2 回答 2

2

一种解决方案是在回调函数中调用“show_message”功能。

apex.server.process
 ("process_selected_callback"
    ,{x01:$my_id}
    ,{type:'GET',
      dataType: 'text',
      success: function( text) {
        apex.submit('DISPLAY_SUCCESS');
      }
     }
 );

但陷阱是,这将始终在处理完成后提交页面,而不管可能发生的任何数据库错误。由于 apex.server.process 不会在 DB 错误时触发,而只是监视 AJAX 调用是否已成功执行。

要解决该问题,您可以返回一个包含实际成功结果的 json 对象。

create or replace package1
  procedure my_process_record
  begin
    apex_json.open_object;

    << place the processing logic here >>

    apex_json.write('success', true);
    apex_json.close_object;
  exception
    when others then
      -- Free all output written so far
      apex_json.free_output;

      -- Create json error object
      apex_json.open_object;
      apex_json.write('success', false);
      apex_json.write('result' , sqlerrm );
      apex_json.close_object;
  end;
end package1;

然后,ajax 调用可以作用于返回的结果标签

apex.server.process
 ("process_selected_callback"
    ,{x01:$my_id}
    ,{type:'GET',
      dataType: 'json',
      success: function( json) {
        if ( json.hasOwnProperty("success") && json.success == true ) {
          apex.submit('DISPLAY_SUCCESS');
        }
        else {
          //Code to show the error
        }
      }
     }
 );

希望这能给你一个方向。

于 2020-07-07T10:33:49.357 回答
1

有两种方法可以做到这一点。

第一种方法:

使用 Javascript 承诺。Apex 让您轻松自如,因为它apex.server.process返回了一个Promise对象。

由于您正在遍历行并为每一行执行回调,因此您可以将每次apex.server.process调用返回的 Promise 存储到一个数组中,然后使用Promise.all()函数等待所有 Promise 被解析(AJAX 请求完成),然后调用apex.submit('DISPLAY_SUCCESS');. 如果您的任何 AJAX 调用可能失败,您可以使用Promise.allSettled()而不是Promise.all()

可以参考this来了解Promise.all()函数 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

第二种方法:

第一种方法似乎效率低下。您是否真的需要为处理的每一行进行单独的 AJAX 调用,因为您所做的似乎只是将 ID 传递给 Package 函数?

为什么不运行一个循环并将所有 ID 存储在一个数组中,然后只进行一次AJAX 调用并将数组传递给它呢?通过 ID 的循环可以通过您的 AJAX PL/SQL 代码完成,这不仅会更快(可能)而且对浏览器来说也更有效,因为它不必运行多个 AJAX 调用和所有相关的开销。

于 2020-07-08T11:21:43.057 回答