Oracle APEX - 如何确保回调在页面提交之前完成
Oracle APEX - how to ensure callback finishes before the page is submitted
我有一个带有自定义按钮的交互式网格。该按钮在单击时处理选定的行:
循环遍历所有选定的行,如果行符合条件,则对每一行执行回调。
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
进程在回调之前执行,因此处理的记录计数仅在显示消息后增加。如何确保回调在页面提交之前完成?
也许有更好的方法来处理选定的行?
一种解决方案是在回调函数中调用“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 不会在数据库错误时触发,而只是监视 AJAX 调用是否已成功执行。
要解决该问题,您可以 return 一个包含实际成功结果的 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 调用可以作用于 returned 结果标签
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
}
}
}
);
希望这个,给你一个方向。
有两种方法可以做到这一点。
第一种方法:
使用Javascript 承诺。 Apex 让您轻松自如 apex.server.process
returns 一个 Promise
对象。
由于您正在遍历行并为每一行执行回调,因此您可以将每个 apex.server.process
调用返回的 Promise 存储到一个数组中,然后使用 Promise.all()
函数等待所有要解决的 Promise(AJAX 请求完成),然后调用 apex.submit('DISPLAY_SUCCESS');
。如果您的任何一个 AJAX 调用可能失败,您可以使用 Promise.allSettled()
而不是 Promise.all()
可以参考这个了解Promise.all()
函数
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
第二种方法:
第一种方法似乎效率低下。您真的需要为处理的每一行进行单独的 AJAX 调用,因为看起来您所做的只是将 ID 传递给包函数吗?
为什么不 运行 一个循环并将所有 ID 存储在一个数组中然后执行 JUST ONE AJAX 调用并将数组传递给它?可以通过您的 AJAX PL/SQL 代码完成 ID 的循环,这不仅会更快(大概)而且对于浏览器来说也更有效,因为它不必 运行 通过多个 AJAX 调用和所有相关开销。
我有一个带有自定义按钮的交互式网格。该按钮在单击时处理选定的行:
循环遍历所有选定的行,如果行符合条件,则对每一行执行回调。
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
进程在回调之前执行,因此处理的记录计数仅在显示消息后增加。如何确保回调在页面提交之前完成?
也许有更好的方法来处理选定的行?
一种解决方案是在回调函数中调用“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 不会在数据库错误时触发,而只是监视 AJAX 调用是否已成功执行。
要解决该问题,您可以 return 一个包含实际成功结果的 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 调用可以作用于 returned 结果标签
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
}
}
}
);
希望这个,给你一个方向。
有两种方法可以做到这一点。
第一种方法:
使用Javascript 承诺。 Apex 让您轻松自如 apex.server.process
returns 一个 Promise
对象。
由于您正在遍历行并为每一行执行回调,因此您可以将每个 apex.server.process
调用返回的 Promise 存储到一个数组中,然后使用 Promise.all()
函数等待所有要解决的 Promise(AJAX 请求完成),然后调用 apex.submit('DISPLAY_SUCCESS');
。如果您的任何一个 AJAX 调用可能失败,您可以使用 Promise.allSettled()
而不是 Promise.all()
可以参考这个了解Promise.all()
函数
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
第二种方法:
第一种方法似乎效率低下。您真的需要为处理的每一行进行单独的 AJAX 调用,因为看起来您所做的只是将 ID 传递给包函数吗?
为什么不 运行 一个循环并将所有 ID 存储在一个数组中然后执行 JUST ONE AJAX 调用并将数组传递给它?可以通过您的 AJAX PL/SQL 代码完成 ID 的循环,这不仅会更快(大概)而且对于浏览器来说也更有效,因为它不必 运行 通过多个 AJAX 调用和所有相关开销。