在我的asp.NET应用程序中,我实现了一个控件,使用服务器端逻辑验证表单输入数据。
我们的想法是将控件拖到需要的地方,在后面的代码中设置它,然后验证表单。 此验证发生在每个字段的onchange事件和表单提交 - 同步ajax调用服务器端。
这一点工作正常,直到我发布到IIS。
问题如下:用户正在文本框中写东西。然后,将焦点放在该文本框上,单击按钮或链接按钮,与要验证的表单无关。 发生验证ajax调用(jQuery onchange触发)并且未到达按钮回发。通过调试我发现问题是ajax调用以某种方式阻止回发发射(几乎感觉像是同步问题)。
我将问题减少到警报似乎与ajax调用相同的程度。请看看以下项目:编辑:链接已删除,因为我无法在同一帖子上发布超过2个链接 - 抱歉!
考虑前两个文本框和按钮: 1)如果您在第一个上写了一些东西,然后单击按钮:onchange将触发,显示警报并且不会发生回发。 2)如果你在第二个上写东西,然后点击按钮:onchange触发和回发发生。
有人可以解释为什么会出现这种情况,以及是否有任何解决方案,即在javascript完成运行后使回发发生火灾?
我可以想出两种方法来解决我的问题,但我需要知道(在文本框更改事件中)用户点击的控件的ID。任何获得它的方式? 这样我就可以:显式触发控件或者验证它是否属于表单控件而不是事件在那一刻验证输入(这是有意义的)。
提前致谢。
EDITED 22-10-2014:
情节变浓。这似乎是同步问题。检查this other test application我删除了警报的位置(由于我没有在我的项目中使用警报框 - 我正在使用小气球),因此过于集中注意并且实际上与问题无关,只是离开了AJAX调用
现在,在服务器端(WebMethod),我放了一个Thread.Sleep()。如果线程睡眠时间过长,似乎错过了回发。就我而言,在我的开发环境中,阈值似乎是80ms。如果ajax调用花费的时间少于~80ms,那么回发就完成了,如果花费的时间超过了,则会错过回发。您看过的任何想法或类似(已解决)的问题?请注意,我的ajax调用具有async:false。
EDITED 24-10-2014:
最后再看看这个。我想我可能已经找到了一个可能的解决方案,虽然我不喜欢依赖setTimeout在'focusin'(同一控件)之前处理提交按钮'click'的想法。
我改变了逻辑(仍然实现了相同的目标),现在使用不同的事件。 现在我需要区分提交控件何时触发'focusin'事件,因为它刚刚获得焦点(1)或点击了它(2):
看看at this new test app,它更接近我在项目中的内容。
你能帮我找到一个更好的方法来处理/处理同一控件上的focusin事件之前的click事件,而没有像setTimeout这样不可预测的东西吗?如果我确实需要依赖setTimeout,你认为等待应该设置多少?在我的机器150ms工作,但在另一个人,它可能需要更多的时间?像某种回调之类的东西是理想的。
再次感谢
答案 0 :(得分:0)
使用__doPostBack(''''');在你的javascript函数结束时
答案 1 :(得分:0)
在这种情况下,警报框似乎会停止回发。我发现的明智的解决方案是使用jQuery对话框,它似乎不会抑制回发。问题当然是对话框不会通过回发继续存在,但是这可以通过一个包含“flag”的隐藏字段来解决,以便在回发后显示对话框。
你需要为对话框添加jquery-ui.js和一些样式,如果这是一个严肃的应用程序,我建议你下载这两个文件并将它们放在脚本文件夹中,就像你已经使用jquery min一样。
<head runat="server">
<title>Postback with dialog</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css">
<script src="scripts/jquery-1.8.2.min.js" type="text/javascript"></script>
<script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#TextBox1").on('change', function(e) {
$("#doDisplayDialog").val("yes"); // Add a flag so it shows after postback.
$('#jqAlert').dialog({
closeOnEscape: true,
open: function(event, ui) {
$(this).parent().appendTo("form");
}
});
});
if ($("#doDisplayDialog").val() == "yes") {
$('#jqAlert').dialog({
closeOnEscape: true,
open: function(event, ui) {
$(this).parent().appendTo("form");
}
});
$("#doDisplayDialog").val("no"); // Clear the flag so it doesn't display after postback.
}
});
</script>
</head>
添加隐藏字段:
<asp:HiddenField ID="doDisplayDialog" runat="server" />
将Div作为对话框:
<div id="jqAlert" title="Alert" style="display: none;">
<p>Postback will happen!</p>
</div>
代码基于您可下载的测试网站应用程序。
- 下面不是一个有效的解决方案 -
尝试此操作 - 在测试Web应用程序中复制/粘贴替换这些行:
$(document).ready(function() {
$("#TextBox1").on('change', function() {
alert('T1 Postback does not fire');
return true;
//return AjaxCall();
});
$("#TextBox2").on('change', function() {
alert('T2 Postback does not fire');
return true;
//return AjaxCall();
});
});
我做的唯一更改是在jquery selector这里用双引号替换单引号
$('#TextBox2')
带
$("#TextBox2")
编辑:实际上它不起作用,我的测试代码中有一个错误。将会更多地了解这一点。