Skip to main content
 首页 » 编程设计

c#之使用 AJAX 调用的 JavaScript 对话框不同步

2024年02月01日32cloudgamer

我在使用某些旨在显示基于 C# ViewModel 的 JQUERY 对话框的 JavaScript 时遇到问题。

我在中继器中有一个 ASP 下拉列表,显示“注册日期”信息。这个想法是当用户从列表中选择一个日期时,JavaScript 对话框将出现,使用特定的 View 模型属性显示与该注册相关的更全面的信息摘要。在相关页面的标准 $(document).ready 上调用函数 CustomerSummary。

JS代码

function CustomerSummary() { 
 
    var registrationId; 
    var data; 
 
    $("select[id$='ddlRegistration']").change(function () { 
        registrationId = $(this).val(); 
 
        if (registrationId !== 'default') 
        { 
            data = MakeAJAXCall(registrationId); 
            $("#dialog").html("Registration Id: " + data.RegistrationId + "<br />" + 
                               "Permit From: " + data.PermitFrom + "<br />" + 
                               "Permit To: " + data.PermitTo + "<br />" + 
                               "Registration Status: " + data.RegistrationStatus  
            ); 
 
            $("#dialog").dialog({ 
 
                show: { 
                    effect: "blind", 
                    duration: 1000 
                }, 
 
                hide: { 
                    effect: "explode", 
                    duration: 1000 
                } 
            }); 
        } 
    }); 
 
    function MakeAJAXCall(regId) 
    { 
        $.ajax({ 
            type: "post", 
            contentType: "application/json; charset=utf-8", 
            dataType: "text json", 
            url: "/Secure/CustomerSummary.aspx/GetRegistration", 
            data: "{ regId: \"" + regId + "\" }", 
 
            success: function (msg) {                 
                data = msg.d;                 
            }, 
 
            error: function (xOptions, textStatus) 
            {                 
                console.log(textStatus); 
                console.log(xOptions); 
            } 
        }); 
    }     
} 

C#代码

[WebMethod(), ScriptMethod(UseHttpGet=false)] 
        public static RegistrationViewModel GetRegistration(int regId) 
        {             
            RegistrationRepository repo = new RegistrationRepository(); 
            RegistrationViewModel reg = new RegistrationViewModel(); 
            RegistrationFactory regFac = new RegistrationFactory(); 
 
            reg = regFac.ConvertToRegistrationViewModel(repo.GetRegistration(regId)); 
 
            return reg; 
        } 

调试期间发生了什么

这里发生的事情是在这条线上:

$("#dialog").html("Registration Id: " + data.RegistrationId + "<br />" + 

我收到错误:

Uncaught TypeError: Cannot read property 'RegistrationId' of undefined  

我第一次从菜单中选择一个日期并调用更改功能时,我得到上面的错误消息,并且没有出现对话框,如果我检查 data 我确实可以看到它未定义。然后,一旦我从下拉菜单中选择了不同的数据,并且我击中了断点 (change.(function) 数据被设置为从先前的 AJAX 调用中检索到的数据,然后弹出对话框up 但使用之前的请求数据,结果会停留在这个循环中,每次我选择一个数据时,我都会看到之前的选择信息。

谁能指出为什么我经常选择不同步,我相信这是由于第一个更改请求,但我不明白为什么 AJAX 调用没有将 data 设置为所需的结果,直到我选择下一个下拉项。

请您参考如下方法:

这行不通

data = MakeAJAXCall(registrationId); 

因为 MakeAJAXCall 正在执行 Ajax 调用并且它是异步的,所以返回的执行顺序与您在函数中返回的顺序不同。因此,您需要使用回调。

尝试将您的代码更改为类似以下内容:

MakeAJAXCall(registrationId, function(data){ 
 $("#dialog").html("Registration Id: " + data.RegistrationId + "<br />" + 
                                   "Permit From: " + data.PermitFrom + "<br />" + 
                                   "Permit To: " + data.PermitTo + "<br />" + 
                                   "Registration Status: " + data.RegistrationStatus  
                ); 
}); 

然后在您的 Ajax 调用中您也需要进行此更改:

function MakeAJAXCall(regId, callback) 
    { 
        $.ajax({ 
            type: "post", 
            contentType: "application/json; charset=utf-8", 
            dataType: "text json", 
            url: "/Secure/CustomerSummary.aspx/GetRegistration", 
            data: "{ regId: \"" + regId + "\" }", 
 
            success: function (msg) {                 
                data = msg.d;   
                callback(data); //<--- You callback function is called here               
            }, 
 
            error: function (xOptions, textStatus) 
            {                 
                console.log(textStatus); 
                console.log(xOptions); 
            } 
        }); 
    }