将 ASP.NET updatepanel 与 jQuery UI DatePicker 组合时出现奇怪的错误
我创建了一个页面,其中结合了内联 jQuery UI datepicker 。当用户单击新日期来更新某些数据时,我不想启动对更新面板的回调。现在,此页面有多个更新面板(不要问:)),因此我需要检查哪个更新面板进行了重新加载,以便在客户端执行一些操作。我使用 __doPostBack
进行回发,并使用 Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, args) {}
监听更新时间 。
问题是在 FF 中回调告诉我这不是一个异步操作,并且我需要检查哪个 updatepanel 执行了更新的数据设置为 null
我的问题是这在 IE 中工作正常,但是 在任何其他浏览器中都没有,这可能是由两件事引起的:IE 进入怪异模式,这解决了问题(这是我的想法),或者 IE 对 updatepanel 有某种本机支持,而其他浏览器没有
。缩小问题范围,并生成一个测试页面:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Test</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js "></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js "></script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<script type="text/javascript">
function doAspNetPostback() {
__doPostBack('<%= hiddenOnSelectionChangedButton.ClientID %>', '');
}
$(document).ready(function() {
/* Create the datepicker */
buildDatepicker();
/* Add callback-method for when the scriptmanager finished a request */
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, args) {
/* Show the panelID - This is 'upd1|hiddenOnSelectionChangedButton' in IE as it should be, and null in Chrome / FF */
alert(sender._postBackSettings.panelID);
});
});
function buildDatepicker() {
var dp = $("#datepicker").datepicker({
onSelect: function(dateText, inst) {
/* Do a postback when someone clicks a date */
doAspNetPostback();
}
});
}
</script>
<div id="datepicker">
</div>
<asp:UpdatePanel UpdateMode="Conditional" ID="upd1" runat="server">
<ContentTemplate>
<asp:Button ID="hiddenOnSelectionChangedButton" Text="Press me" runat="server" />
<div id="lala" runat="server">
Upd1
</div>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
在 IE 中启动此测试页面将导致一个消息框显示其应有的内容,而在 FF 或 Chrome 中加载它会导致一个消息框显示“null”:)
我尝试过各种各样的事情,但我不确定什么会导致这种行为,因为我并没有真正深入了解 jQuery 或 ASP.NET Ajax 的内部工作原理。但是,如果我在 FireBug 中单步执行代码的速度足够慢,它就可以工作......这让我认为这可能是 jQuery 回调和 ASP.NET Ajax 回调之间的互操作性问题?
任何帮助或想法将不胜感激。
谢谢。
[更新]蒂姆解决了它!多谢! - 也感谢所有花时间试图解决这个问题的人:)
I've created a page which combines an inline jQuery UI datepicker . I wan't to initiate a callback to the updatepanel when the user clicks a new date to update some data. Now, this page has multiple updatepanels (don't ask :) ), so I need to check which updatepanel did the reload in order to do some stuff clientside. I'm using __doPostBack
to do the postback and Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, args) {}
to listen for when an update is done.
The problem is that in FF the callback tells me that it's not an async operation, and the data I need to have to check which updatepanel did the update is set to null.
My problem is that this works fine in IE, but not in any other browser, which could be caused by 2 things: IE goes into a quirksmode which resolves the issue (this is what I think) or that IE has some sort of native support for the updatepanel that other browsers dont.
I've narrowed the problem down, and produced a testpage:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Test</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js "></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js "></script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<script type="text/javascript">
function doAspNetPostback() {
__doPostBack('<%= hiddenOnSelectionChangedButton.ClientID %>', '');
}
$(document).ready(function() {
/* Create the datepicker */
buildDatepicker();
/* Add callback-method for when the scriptmanager finished a request */
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, args) {
/* Show the panelID - This is 'upd1|hiddenOnSelectionChangedButton' in IE as it should be, and null in Chrome / FF */
alert(sender._postBackSettings.panelID);
});
});
function buildDatepicker() {
var dp = $("#datepicker").datepicker({
onSelect: function(dateText, inst) {
/* Do a postback when someone clicks a date */
doAspNetPostback();
}
});
}
</script>
<div id="datepicker">
</div>
<asp:UpdatePanel UpdateMode="Conditional" ID="upd1" runat="server">
<ContentTemplate>
<asp:Button ID="hiddenOnSelectionChangedButton" Text="Press me" runat="server" />
<div id="lala" runat="server">
Upd1
</div>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
Firing this testpage up in IE will result in a messagebox which shows what it's supposed to, while loading it in FF or Chrome results in a messagebox which says "null" :)
I've tried all sorts of things, but I'm unsure of what could cause this behaviour as I'm not really that deep into the inner workings of jQuery or ASP.NET Ajax. However, if I step through the code in FireBug slow enough it works ... Which leads me to think it might be a problem with interoperability between jQuery callbacks and ASP.NET Ajax callbacks?
Any help or ideas will be highly appreciated.
Thanks.
[UPDATE] Tim solved it! Thanks a lot! - Also thanks to everyone who spent their time trying to figure this out :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
我想您会发现 MSDN 上的这篇文章很有趣: http://msdn.microsoft .com/en-us/magazine/cc163413.aspx
文章说“Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(”也附加到 Updatepanel 完成事件。
然后在您的处理程序中,您可以循环遍历更新的面板,
我会避免使用 _ postBackSettings,因为“ _ ”表示隐私,并且可能会在 ASP.NET ajax 的未来版本中停止使用。
I think you my find this article from MSDN interesting: http://msdn.microsoft.com/en-us/magazine/cc163413.aspx
The article says that "Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(" also attaches to Updatepanel complete events.
then in your handler you can loop through the updatedpanels with
I would stray away from using the _ postBackSettings because of the " _ " denotes privacy and may be discontinued in future versions of asp.net ajax.
我使用 ScriptManager 上的 ScriptMode="Release" 参数修复了 jQuery/Updatepanels 的各种异步问题。
I have fixed various async issues with jQuery/Updatepanels using the ScriptMode="Release" argument on the ScriptManager.
AJAX 和 jQuery 组合的一个常见问题是,这......
仅发生在第一页加载时。如果替换受 buildDatapicker() 影响的 HTML 区域;您丢失了附加到它的所有事件(即使您已将其替换为相同的元素)。
您需要做的就是针对新加载的 HTML 调用 buildDatepicker...并传入已加载的元素以确保不会重复...
现在您可以调用 buildDatepicker(myNewlyLoadedElement);重新绑定数据选择器功能。
A common problem with combinations of AJAX and jQuery is that this...
Only happens on the first page load. If you replace the area of HTML that has been affected by buildDatapicker(); you lost any events that were attached to it (even if you've replaced it with the same elements).
All you need to do is call buildDatepicker against the newly loaded HTML... and pass in the element that has been loaded just to ensure you don't double up...
Now you can call buildDatepicker(myNewlyLoadedElement); to re-bind the data picker functionality.
您可以尝试使用 datepicker 设置 altField 并检查更改以进行回发。
You could try using datepicker to set an altField and check that for changes to do a postback.
我已经尝试过您的代码来重现该错误,并且我可以重现该错误。我得出的结论是 jQuery/UpdatePanels 存在一些问题。
如果我用 LinkButton 替换按钮,您可以看到链接直接调用 __doPostBack(...),这是与您调用的参数完全相同的函数。直接单击链接按钮可以,但单击日期则不行。
所以这意味着 jQuery 内部发生了一些改变某些上下文的事情。但我不知道那会是什么。
I have tried your code for reproducing the error and I can reproduce the error. And I've come to the conclusion that there is some problem with jQuery/UpdatePanels.
If I replace the button with a LinkButton, you can see that the link directly calls __doPostBack(...), the exact same function with the exact same arguments that you are calling. And clicking the link button directly works, but clicking a date doesn't.
So that means that something happens inside jQuery that changes some context. But I have no idea what that would be.
不久前我发现了另一个脚本,我已经使用了一段时间并且从未遇到过任何问题。
您仍然可以像在上面的脚本中一样手动设置回调函数。
您可能还必须手动添加脚本资源处理程序(不记得是哪一个),但我特别记得调用异步和非异步回发时遇到问题。希望有帮助。
I found another script a while back that I've been using for a while now and have never had any problems with.
You can still manually set a callback function exactly like you do in your above script.
You may also have to manually add a scriptresource handler (Can't remember which one) but I specifically remember having problems calling async and non-async post backs. Hope that helps.
看起来像竞争条件,请尝试 UpdateMode="Conditional" 和 ChildrenAsTriggers="false",参考。
Looks like a race condition, try UpdateMode="Conditional" and ChildrenAsTriggers="false", reference.
哦?为什么不给它一点时间来解决它呢?
Oh? Why not give it a second to work it out?
我喜欢蒂姆的回答,围绕着你应该在 pageLoaded 事件中使用 args.get_PanelsUpdated() 的想法。这似乎是完成您尝试做的事情的适当方法。尝试一下——如果不起作用,那么我还有另一个想法(尽管它有点肮脏)。
I liked Tim's answer, surrounding the idea that you should be using args.get_PanelsUpdated() in the pageLoaded event. It seems like the appropriate means for doing what you're attempting to do. Try it out -- if it doesn't work, then I've got another idea up my sleeve (though its kind of dirty).
我认为这很有趣,如果您在 doPostBack 之后添加警报,那么 FF 不会返回 null。
I thought this was interesting, if you add an alert after the doPostBack then FF doesn't return null.