我遇到一些JavaScript的问题,它打算显示基于C#ViewModel的JQUERY对话框。
我在转发器中有一个ASP下拉列表,显示“注册日期”信息。这个想法是当用户从列表中选择日期时,将出现JavaScript对话框,显示使用特定视图模型属性的与该注册相关的信息的更全面的摘要。对于相关页面,将在标准$(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调用中检索到的数据,则会弹出对话框但是包含先前的请求数据,结果然后保持在这个循环中,每当我选择一个数据时,我会使用之前的选择信息。
任何人都可以指出为什么我不断地选择一个不同步,我相信它是由于第一个更改请求但我不明白为什么AJAX调用没有将data
设置为所需的结果直到我选择下一个下拉项目。
答案 0 :(得分:3)
这不起作用
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);
}
});
}
答案 1 :(得分:2)
Ajax中的第一个A用于异步。这意味着您的呼叫将在后台运行,这就是您使用回调的原因。当您的呼叫以成功/错误完成时,例如10秒后,将调用正确的功能。同时,您设置和创建结果的其他代码也会运行,最有可能在从ajax查询收到任何答案之前运行。正如@Dalorzo建议的那样,将结果对话框代码包装在回调函数中,这样您的代码将在收到结果后运行。