首页 > 解决方案 > asp页面中的Javascript回调

问题描述

我已经查看了这个How-do-i-return-the-response-from-an-asynchronous-callwhy-is-my-variable-unaltered-after-i-modify-it-inside-of-a -function-asynchron,但我试图做的不起作用。

由于我们的一些用户使用 IE,我们似乎不得不依赖回调。

这个问题的背景来自之前的帖子。旧代码使用 VBscript 的 MsgBox,但现在必须将相同的功能移植到 Javascript。

为了提供上下文,工具栏上有一堆按钮(因此是toolbar.asp),例如“新建”、“更新”、“删除”。用户可以导航到系统的某些部分,例如为特定资源/人员创建“新”记录。详细信息和功能显示在屏幕的主要部分(因此为 main.asp)。该系统最初是在大约 15 年前(或更长时间)编写的。当用户单击toolbar.asp 上的“更新”时,这取决于main.asp 显示的是哪个屏幕。main.asp 中的 dovalidation() 部分可以被交换(就像从数据库中获取脚本一样)并根据用户的位置和位置插入 dovalidation() 中。所以有些部分仍在 Visual Basic 6 中,但似乎他们正试图用 Javascript 替换 VBscript。

因此,用户在特定屏幕上并单击更新(工具栏.aspdoupdate()被调用)。这doupdate()会对日期和其他变量以及 main.asp 的调用进行大量检查dovalidation()。根据用户找到自己的位置,dovalidation看起来会有所不同。在很多情况下,如我正在谈论的特定示例中,VBscript 代码中曾经有一个 MsgBox,它为用户提供了一个选择,具体取决于到目前为止所做的验证。但是,该 VBscript 现在应该被 Javascript 替换。看来我的老板不想使用普通的 window.confirm,因为她希望能够自定义按钮。

VBscript 的 MsgBox 阻止了进一步的执行,但现在使用jquery 确认没有相同的结果,因为它是非阻塞的。

如果验证发生的方式是向用户提供确认对话框,并且用户单击“取消”,则不应显示下一页,但目前,无论用户是否单击“取消”,几秒钟后显示下一页。在doupdate()函数的末尾有: parentMain.screenform.submit(); 这可能是我的回调不起作用的部分原因吗?

在工具栏.asp 文件中,这在 doupdate() 函数中被调用:

//... Other code that determines variables, fringe scenarios etc.
//... 

// Then dovalidation() (in which the blocking MsgBox used to be) is called:

var sErr = parentMain.dovalidation();
        if (sErr != ""){
            return;
        }


//Then the rest of the code which is executed irrespective of the jquery confirm.

//do update
    try {
        parentMain.document.all("Updating").value = "YES"
        parentMain.document.body.scrollTop = 0
        parentMain.document.body.scroll = 'no'
        parentMain.ShowBusy();
        document.getElementById("sysBusy").value = "true";
        //parentMain.document.all("clockFrame").style.display = "block";
    } catch(e) {
        return (e)
    }

    //do check for resource tag
    if (sScreenType.toUpperCase() == "RESOURCE TABLE") {
        if (lResource == "0") {
            parentMain.document.all("sysresource").value = lDetailResource
        }
        //alert("looping for resource tag");
        var sField = ""
        var sCheck = "Resource Tag"
        if (!(sScreen == "Resource")) {
            /*********************************************************************/
            /** loop through the fields and update resouce tag if empty - submit**/
            /*********************************************************************/
            var elements = parentMain.document.getElementById("screenform").elements;

            for (var i = 0, element; element = elements[i++];) {
               if ((element.name).indexOf(sCheck) > 0) {
                    var sValue = element.value
                    if (sValue.length == 0) {
                        element.value = lDetailResource
                    }
                }
                if ((element.tagName.toUpperCase()) == "SELECT") {
                    if (element.disabled == true) {
                        element.disabled = false;
                    }
                }
            }
        }
        
    }
  
    //submit screen

    parentMain.screenform.submit(); //<-- Could this be part of the problem?
    
    }

dovalidation函数位于 main.asp 文件中。根据情况更换部分dovalidation功能。这是标记之间//################

function dovalidation() {
msErr = "";
         
//#################
if (msErr.length == 0) {

var vEffectiveDate="";
var vLastRunDate="";
var sStatus="";
var vMsg="";
var sResponse="";
vEffectiveDate = document.getElementById("Smoke.Effective Date").value;
vLastRunDate = document.getElementById("Smoke.Last Run Date").value;
sStatus  = document.getElementById("Smoke.Calc Status").value;
vMsg = "";
if ((sStatus).length == 0  ){
    sStatus = "SUCCESFUL";
    //document.getElementById("Smoke.Calc Status").value= sStatus;
}
if ((vEffectiveDate).length > 0  ){
    if (!isDate(vEffectiveDate)  ){
        vMsg = vMsg+"[Effective Date] Is not a date." + ";\r\n";
    } else if (  moment( toDate(vEffectiveDate)).isBefore(toDate(vLastRunDate)) ){
        vMsg = vMsg+"[Effective Date] cannot be on/before "+vLastRunDate+"." + ";\r\n";
    }
}
if (sStatus.toUpperCase() != "SUCCESFUL") {
    $.confirm({
        title:  "Confirmation",
        columnClass: 'col-md-6 col-md-offset-3', 
        content:"Forecast calculation still busy. Results might not be accurate. Continue?",
        buttons: {
            confirm: function() {
                sResponse= "1";
                vMsg = "Response 1";                
                processMessage(); // <--- added this
            },
            cancel: function() {
                sResponse= "2";
                vMsg = "Response 2";                
                // Moved code here, as it needs to execute when Cancel is clicked
                $.alert({
                    title: "INFORMATION",
                    columnClass: 'col-md-6 col-md-offset-3',
                    content: "Screen will refresh. Please click on Update to try again.",
                    // Code that should execute when alert is closed:
                    onAction: function () {
                        document.getElementById("Smoke.Calc Status").value= "REFRESH";
                        msErr = "ABORT";
                        processMessage(); // <--- added this
                    }
                });
            },
        }
    });
} else { // <-- added
    processMessage();
}

function processMessage() {
    // Moved code in a function, as it should only execute after confirm/alert is closed 
    if (vMsg != "") {
        $.alert({
            title: 'Validation Message',
            columnClass: 'col-md-6 col-md-offset-3',    
            content: vMsg,
        });
        msErr = "ERROR";
        
    }
  }
 }                     
//#################
          
return msErr;   
}

所以我认为我的问题在于msErr在用户有机会决定选择确认对话框上的哪个按钮之前很久就被退回。如果我没有设置断点并单击确认的取消,那么我确实看到显示了警报,但页面没有刷新 ( document.getElementById("Smoke.Calc Status").value= "REFRESH";) 并且显示了下一页。我认为这是来自sErr == ""toolbar.asp文件中的,然后程序流程只是继续。

无论如何,我尝试使用回调,但情况没有改变。

这是我试图做的:

parentMain.dovalidation(function(result){
    if (result != ""){
        return;
    }
    });

在 main.asp 中的 dovalidation 函数:

function dovalidation(callback) {
 msErr = "";
         
//#################
if (msErr.length == 0) {

    var vEffectiveDate="";
    var vLastRunDate="";
    var sStatus="";
    var vMsg="";
    var sResponse="";
    vEffectiveDate = document.getElementById("Smoke.Effective Date").value;
    vLastRunDate = document.getElementById("Smoke.Last Run Date").value;
    sStatus  = document.getElementById("Smoke.Calc Status").value;
    vMsg = "";
    if ((sStatus).length == 0  ){
        sStatus = "SUCCESFUL";
        document.getElementById("Smoke.Calc Status").value= sStatus;
    }
    if ((vEffectiveDate).length > 0  ){
        if (!isDate(vEffectiveDate)  ){
            vMsg = vMsg+"[Effective Date] Is not a date." + ";\r\n";
        } else if (  moment( toDate(vEffectiveDate)).isBefore(toDate(vLastRunDate)) ){
            vMsg = vMsg+"[Effective Date] cannot be on/before "+vLastRunDate+"." + ";\r\n";
        }
    }
    if (sStatus.toUpperCase() != "SUCCESFUL") {
        $.confirm({
            title:  "Confirmation",
            columnClass: 'col-md-6 col-md-offset-3', 
            content:"Forecast calculation still busy. Results might not be accurate. Continue?",
            buttons: {
                confirm: function() {
                    sResponse= 1;
                    vMsg = "Response 1";
                    processMessage(); // <--- added this
                },
                cancel: function() {
                    sResponse= 2;
                    vMsg = "Response 2";
                    // Moved code here, as it needs to execute when Cancel is clicked
                    $.alert({
                        title: "INFORMATION",
                        columnClass: 'col-md-6 col-md-offset-3',
                        content: "Screen will refresh. Please click on Update to try again.",
                        // Code that should execute when alert is closed:
                        onAction: function () {
                            document.getElementById("Smoke.Calc Status").value= "REFRESH";
                            msErr = "ABORT";
                            processMessage(); // <--- added this
                        }
                    });
                },
            }
        });
    } else { // <-- added
        processMessage();
    }
    
    function processMessage() {
        // Moved code in a function, as it should only execute after confirm/alert is closed 
        if (vMsg != "") {
            $.alert({
                title: 'Validation Message',
                columnClass: 'col-md-6 col-md-offset-3',    
                content: vMsg,
            });
            msErr = "ERROR";
        }
    }
}
//#################         
callback(msErr);   
} 

所以,它不能正常工作,我不知道我做错了什么,但我想我没有正确使用回调。它在两个不同的文件中会有所不同吗?考虑到它们之间的部分//#########被交换,这必须起作用。

我将不胜感激任何反馈和指导。

标签: javascript

解决方案


没有必要涉及 jQuery。

JavaScript 有函数alert,它们是同步confirmprompt(即阻塞执行直到它们返回),就像MsgBox以前一样。

因此,如果这对您来说更容易,您可以以这种方式保留原始代码结构。因为正如“我如何从异步调用返回响应”一文中解释的那样,您不能让dovalidation函数返回任何取决于$.confirm您当前使用的异步操作结果的内容,因为这需要时间旅行;) - 但你可以让它依赖于同步操作,比如 JS 的内置confirm.


推荐阅读