【问题标题】:JavaScript dialog using AJAX call is out of sync使用 AJAX 调用的 JavaScript 对话框不同步
【发布时间】:2014-09-01 14:10:36
【问题描述】:

我遇到了一些 JavaScript 问题,该 JavaScript 旨在显示基于 C# ViewModel 的 JQUERY 对话框。

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

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 调用中检索到的数据,然后会弹出对话框但使用之前的请求数据,结果然后停留在这个循环中,每次我选择一个数据时,我都会看到以前的选择信息。

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

【问题讨论】:

    标签: c# javascript ajax dialog


    【解决方案1】:

    这行不通

    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 Call 中,您也需要进行此更改:

    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);
                }
            });
        }    
    

    【讨论】:

      【解决方案2】:

      Ajax 中的第一个 A 用于异步。这意味着您的呼叫将在后台运行,这就是您使用回调的原因。当您的呼叫以成功/错误完成时,例如 10 秒后,将调用正确的函数。同时,您设置和创建结果的其他代码也运行,很可能在从 ajax 查询收到任何答案之前运行。正如@Dalorzo 建议的那样,将您的结果对话框代码包装在回调中,这样您的代码将在收到结果后运行

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多