javascript 和 plsql 任务之间的动态操作交互

Interaction in a Dynamic action between javascript and plsql tasks

我正在尝试在动态操作中执行几个 pl/sql 块,并通过报告当前状态的模态对话框向最终用户反馈。

类似于:

Processing Step 1...

/*Run pl/sql code for step 1*/

Processing Step 2...

/*Run pl/sql code for Step 2*/

等等...

pl/sql 和 javascript 代码,运行 都符合预期,但是当我按顺序将它们组合到动态操作中时:

1 - 执行 Javascript

2 - 执行 PL/SQL 块 /* 选中等待结果选项*/

3 - 执行 Javascript

4 - 执行PL/SQL块

未显示状态对话框,但是 pl/sql 块已顺利完成。

我意识到这一定是与 javascript 相关的东西不是多线程的,所以我将 pl/sql 块移动到应用程序进程并将它们 运行 作为 ajax 这样调用:

function something(){
    var get;
    var result = 0;
    updateStatus('Running Step1');
    get = new htmldb_Get(null,$v('pFlowId'),'APPLICATION_PROCESS=P6_STEP_1',0);
    result = get.get();
    if(result > 0){
        updateStatus('Running Step 2');
        get = new htmldb_Get(null,$v('pFlowId'),'APPLICATION_PROCESS=P6_STEP_2',0);
        result = get.get();
    }
    closeStatusDialog();
}

但是,和以前一样,进程 运行 正常,但对话框没有出现。最后我为每个调用添加了一个 setTimeOut 函数,像这样:

function something(){
    var get;
    var result = 0;
    updateStatus('Running Step1');
    get = new htmldb_Get(null,$v('pFlowId'),'APPLICATION_PROCESS=P6_STEP_1',0);
    result = setTimeOut(get.get(),500);
    if(result > 0){
        updateStatus('Running Step 2');
        get = new htmldb_Get(null,$v('pFlowId'),'APPLICATION_PROCESS=P6_STEP_2',0);
        result = setTimeOut(get.get(),500);
    }
    closeStatusDialog();
}

但还是一无所获。我该怎么做才能根据需要获得此 运行ning?。

我检查了浏览器控制台,没有抛出异常,pl/sql 块也是如此。

我已经解决了,虽然解决方案不依赖于动态操作,只是 javascript 和应用程序进程。我将此发布给有类似问题的任何人。

htmldb_Get Javascript 对象是 XMLHttpRequest AJAX 对象的 oracle-apex 包装器。虽然记录不佳。

我找到了代码的副本(在底部),结果发现它有另一个名为 GetAsync 的函数,它允许将函数作为参数传递给 onreadystatechange XMLHttpRequest 对象上的属性,每次底层 XMLHttpRequest 的属性 readyState 更改时都会执行。

作为参数传递的函数不能在它自己的定义中有参数。

因此,您需要调用 GetAsync(someFunction)

而不是在 htmldb_Get 对象上调用 get()

在我的案例中使用这个解决方案:

function something(){
    var get;
    get = new htmldb_Get(null,$v('pFlowId'),'APPLICATION_PROCESS=P6_STEP_1',0);
    get.GetAsync(someFunctionStep1);
}

function someFunctionStep1(){
    if(p.readyState == 0){ /*p is the underlying XMLHttpRequest object*/
        console.log("request not initialized");
        updateStatus('Running Step 1');
    } else if(p.readyState == 1){
        console.log("server connection established");
    } else if(p.readyState == 2){
        console.log("request received");
    } else if(p.readyState == 3){
        console.log("processing request");
    } else if(p.readyState == 4){
        console.log("request finished and response is ready");
        callStep2();
    }
}

function callStep2(){
    var get;
    get = new htmldb_Get(null,$v('pFlowId'),'APPLICATION_PROCESS=P6_STEP_2',0);
    get.GetAsync(someFunctionStep2);
}

function someFunctionStep2(){
    if(p.readyState == 0){
        console.log("request not initialized");
        updateStatus('Running Step 2');
    } else if(p.readyState == 1){
        console.log("server connection established");
    } else if(p.readyState == 2){
        console.log("request received");
    } else if(p.readyState == 3){
        console.log("processing request");
    } else if(p.readyState == 4){
        console.log("request finished and response is ready");
        closeDialog();
    }
}

这里是htmldb_get的定义,最后是GetAsync函数

/*
  str should be in the form of a valid f?p= syntax
*/

function htmldb_Get(obj,flow,req,page,instance,proc,queryString) {
  //
  // setup variables
  //
  this.obj      = $x(obj);                   // object to put in the partial page
  this.proc     = proc != null ? proc  : 'wwv_flow.show'; // proc to call 
  this.flow     = flow != null ? flow  : $x('pFlowId').value;          // flowid
  this.request  = req  != null ? req  : '';               // request 
  this.page     = page; // page
  this.params   = '';   // holder for params
  this.response = '';   // holder for the response
  this.base     = null; // holder fot the base url
  this.queryString = queryString!= null ? queryString : null ; // holder for passing in f? syntax
  this.syncMode     = false;
  //
  // declare methods
  //

  this.addParam     = htmldb_Get_addParam;
  this.add          = htmldb_Get_addItem;
  this.getPartial   = htmldb_Get_trimPartialPage;
  this.getFull      = htmldb_Get_fullReturn;
  this.get          = htmldb_Get_getData;
  this.url          = htmldb_Get_getUrl;
  this.escape       = htmldb_Get_escape;
  this.clear        = htmldb_Get_clear;
  this.sync         = htmldb_Get_sync;
  this.setNode      = setNode;
  this.replaceNode  = replaceNode
  //
  // setup the base url
  //
   var u = window.location.href.indexOf("?") > 0 ?
             window.location.href.substring(0,window.location.href.indexOf("?"))
             : window.location.href;
   this.base = u.substring(0,u.lastIndexOf("/"));

   if ( this.proc == null || this.proc == "" ) 
           this.proc = u.substring(u.lastIndexOf("/")+1);

   this.base = this.base +"/" + this.proc;


  //
  // grab the instance form the page form   
  //
  if ( instance == null || instance == "" ) {
    var pageInstance = document.getElementById("pInstance");
      if ( typeof(pageInstance) == 'object' ) {
        this.instance = pageInstance.value;
      }
  } else {
    this.instance = instance;
  }


  //
  // finish setiing up the base url and params
  //
  if ( ! queryString ) {
      this.addParam('p_request',     this.request) ;
      this.addParam('p_instance',    this.instance);
      this.addParam('p_flow_id',     this.flow);
      this.addParam('p_flow_step_id',this.page);
  }

  function setNode(id) {
    this.node = html_GetElement(id);
  }
  function replaceNode(newNode){
      var i=0;
      for(i=this.node.childNodes.length-1;i>=0;i--){
        this.node.removeChild(this.node.childNodes[i]);
      }
      this.node.appendChild(newNode);
  }
}
function htmldb_Get_sync(s){
  this.syncMode=s;
}

function htmldb_Get_clear(val){
  this.addParam('p_clear_cache',val);
}

//
// return the queryString
//
function htmldb_Get_getUrl(){
    return this.queryString == null ? this.base +'?'+ this.params : this.queryString;
}

function htmldb_Get_escape(val){
    // force to be a string
     val = val + "";
     val = val.replace(/\%/g, "%25");
     val = val.replace(/\+/g, "%2B");
     val = val.replace(/\ /g, "%20");
     val = val.replace(/\./g, "%2E");
     val = val.replace(/\*/g, "%2A");
     val = val.replace(/\?/g, "%3F");
     val = val.replace(/\/g, "%5C");
     val = val.replace(/\//g, "%2F");
     val = val.replace(/\>/g, "%3E");
     val = val.replace(/\</g, "%3C");
     val = val.replace(/\{/g, "%7B");
     val = val.replace(/\}/g, "%7D");
     val = val.replace(/\~/g, "%7E");
     val = val.replace(/\[/g, "%5B");
     val = val.replace(/\]/g, "%5D");
     val = val.replace(/\`/g, "%60");
     val = val.replace(/\;/g, "%3B");
     val = val.replace(/\?/g, "%3F");
     val = val.replace(/\@/g, "%40");
     val = val.replace(/\&/g, "%26");
     val = val.replace(/\#/g, "%23");
     val = val.replace(/\|/g, "%7C");
     val = val.replace(/\^/g, "%5E");
     val = val.replace(/\:/g, "%3A");
     val = val.replace(/\=/g, "%3D");
     val = val.replace(/$/g, "%24");
     //val = val.replace(/\"/g, "%22");
    return val;
}

//
// Simple function to add name/value pairs to the url
//
function htmldb_Get_addParam(name,val){
    if ( this.params == '' ) 
     this.params =  name + '='+ ( val != null ? this.escape(val)  : '' );
  else
     //this.params = this.params + '&'+ name + '='+ ( val != null ? val  : '' );
     this.params = this.params + '&'+ name + '='+ ( val != null ? this.escape(val)  : '' );
     return;
}


//
// Simple function to add name/value pairs to the url
//
function htmldb_Get_addItem(name,value){
  this.addParam('p_arg_names',name);
  this.addParam('p_arg_values',value);  
}

//
// funtion strips out the PPR sections and returns that
//
function htmldb_Get_trimPartialPage(startTag,endTag,obj) {
   setTimeout(html_processing,1);
   if (obj) {this.obj = $x(obj);}
   if (!startTag){startTag = '<!--START-->'};  
   if (!endTag){endTag  = '<!--END-->'};
   var start = this.response.indexOf(startTag);
   var part;
   if ( start >0 ) {
       this.response  = this.response.substring(start+startTag.length);
       var end   = this.response.indexOf(endTag); 
       this.response  = this.response.substring(0,end);
   }         
       if ( this.obj ) {
          if(this.obj.nodeName == 'INPUT'){
            if(document.all){
              gResult = this.response;
              gNode = this.obj;
              var ie_HACK = 'htmldb_get_WriteResult()';
              setTimeout(ie_HACK,100);
            }else{
              this.obj.value = this.response;
            }
          }else{
            if(document.all){
              gResult = this.response;
              gNode = this.obj;
              var ie_HACK = 'htmldb_get_WriteResult()';
              setTimeout(ie_HACK,100);
            }else{
              this.obj.innerHTML = this.response;
            }
          }
       }
   //window.status = 'Done'
   setTimeout(html_Doneprocessing,1);
   return this.response;
}


var gResult = null;
var gNode = null
function htmldb_get_WriteResult(){
    if(gNode && ( gNode.nodeName == 'INPUT' || gNode.nodeName == 'TEXTAREA')){
    gNode.value = gResult;
    }else{
    gNode.innerHTML = gResult;
    }
    gResult = null;
    gNode = null;
  return;
}

//
// function return the full response
//
function htmldb_Get_fullReturn(obj) {
   setTimeout(html_processing,1);
   if (obj) { this.obj = html_GetElement(obj);}

       if ( this.obj ) {
          if(this.obj.nodeName == 'INPUT'){
            this.obj.value = this.response;
          }else{
            if(document.all){
              gResult = this.response;
              gNode = this.obj;
              var ie_HACK = 'htmldb_get_WriteResult()';
              setTimeout(ie_HACK,10);
            }else{
              this.obj.innerHTML = this.response;
            }
          }
       }
       setTimeout(html_Doneprocessing,1);
  return this.response;
}

//
// Perform the actual get from the server
//
function htmldb_Get_getData(mode,startTag,endTag){
   html_processing();
   var p;
   try {
      p = new XMLHttpRequest();
    } catch (e) {
      p = new ActiveXObject("Msxml2.XMLHTTP");
    }
    try {
        var startTime = new Date();
        p.open("POST", this.base, this.syncMode);           
        p.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        p.send(this.queryString == null ? this.params : this.queryString );
        this.response = p.responseText;
        if ( this.node ) 
         this.replaceNode(p.responseXML);
        if ( mode == null || mode =='PPR' ) {
            return this.getPartial(startTag,endTag);
        } if ( mode == "XML" ) {
            setTimeout(html_Doneprocessing,1);
            return p.responseXML;
        } else {
            return this.getFull();
        }

    } catch (e) {
       setTimeout(html_Doneprocessing,1);
       return;
    }
 }

function html_Doneprocessing(){
  document.body.style.cursor="default";
}

function html_processing(){
    document.body.style.cursor="wait";
}

/* 
this adds better aysnc functionality 
to the htmldb_Get object 
pVar is the function that you want to call when the xmlhttp state changes
in the function specified by pVar the xmlhttp object can be referenced by the variable p
*/
htmldb_Get.prototype.GetAsync = function(pVar){
   try{
      p = new XMLHttpRequest();
    }catch(e){
      p = new ActiveXObject("Msxml2.XMLHTTP");
    }
    try {
        var startTime = new Date();
            p.open("POST", this.base, true);
            if(p) {
                    p.onreadystatechange = pVar;
                    p.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                    p.send(this.queryString == null ? this.params : this.queryString );
                    return p;
        } 
        }catch(e){
      return false;
    }
 }



 /* PDF OUTPUT */
/*Gets PDF src XML */



function htmldb_ExternalPost(pThis,pRegion,pPostUrl){
   var pURL = 'f?p='+html_GetElement('pFlowId').value+':'+html_GetElement('pFlowStepId').value+':'+html_GetElement('pInstance').value+':FLOW_FOP_OUTPUT_R'+pRegion
   document.body.innerHTML = document.body.innerHTML + '<div style="display:none;" id="dbaseSecondForm"><form id="xmlFormPost" action="' + pPostUrl + '?ie=.pdf" method="post" target="pdf"><textarea name="vXML" id="vXML" style="width:500px;height:500px;"></textarea></form></div>';
   var l_El = html_GetElement('vXML');
   var get = new htmldb_Get(l_El,null,null,null,null,'f',pURL.substring(2));
   get.get();
   get = null;
   setTimeout('html_GetElement("xmlFormPost").submit()',10);
  return;
}


function $xml_Control(pThis){
        this.xsl_string = '<?xml version="1.0"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html"/><xsl:param name="xpath" /><xsl:template match="/"><xsl:copy-of select="//*[@id=$xpath]"/></xsl:template></xsl:stylesheet>';
        if(document.all){
            this.xsl_object = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.3.0");
            this.xsl_object.async=false;
            this.xsl_object.loadXML(this.xsl_string)
            tmp = new ActiveXObject("Msxml2.XSLTemplate.3.0");
            tmp.stylesheet = this.xsl_object;
            this.xsl_processor = tmp.createProcessor();
        }else{
          this.xsl_object = (new DOMParser()).parseFromString(this.xsl_string, "text/xml");
            this.xsl_processor = (new XSLTProcessor());
            this.xsl_processor.importStylesheet(this.xsl_object);
            this.ownerDocument = document.implementation.createDocument("", "test", null);
        }
        this.xml = pThis;
        this.CloneAndPlace = _CloneAndPlace;
        return

        function _CloneAndPlace(pThis,pThat,pText){
           var lThat = $x(pThat);
             if(document.all){
                this.xsl_processor.addParameter("xpath", pThis);
                this.xsl_processor.input = this.xml;
                this.xsl_processor.transform;
                var newFragment = this.xsl_processor.output;
             }else{
                 this.xsl_processor.setParameter(null, "xpath", pThis);
                 var newFragment = this.xsl_processor.transformToFragment(this.xml,this.ownerDocument);
             }
             if(lThat){
                if(document.all){
                 lThat.innerHTML='';
                 lThat.innerHTML=newFragment;
                }else{
                 lThat.innerHTML='';
                 lThat.appendChild(newFragment);
                }
             /*
             in IE newFragment will be a string
             in FF newFragment will be a dome Node (more useful)
             */
             return newFragment;
             }
        }
}