将ASP.NET updatepanel与jQuery UI DatePicker结合使用时出现了奇怪的错误

我创建了一个结合了内联jQuery UI datepicker的页面 。 当用户单击新日期以更新某些数据时,我不想发起对updatepanel的回调。 现在,这个页面有多个updatepanels(不要问:)),所以我需要检查哪个updatepanel重新加载,以便做一些客户端的东西。 我正在使用__doPostBack来进行回发,并使用Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, args) {}来监听更新何时完成。

问题是在FF中,回调告诉我它不是异步操作,而我需要检查哪个更新面板将更新设置为null。

我的问题是,这在IE中运行良好,但在任何其他浏览器中都没有,这可能是由两件事引起的:IE进入一个解决问题的怪癖模式(这是我的想法)或IE有某种原生支持对于其他浏览器不知道的updatepanel。

我把问题缩小了,并制作了一个测试页:

    Test     
function doAspNetPostback() { __doPostBack('', ''); } $(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(); } }); }
Upd1

在IE中启动此测试页将导致一个消息框显示它应该是什么,而在FF或Chrome中加载它会导致消息框显示“null”:)

我已经尝试了各种各样的东西,但我不确定是什么原因可能导致这种行为,因为我并没有真正深入到jQuery或ASP.NET Ajax的内部工作中。 但是,如果我在FireBug中逐步执行代码的速度足够有效……这让我认为jQuery回调和ASP.NET Ajax回调之间的互操作性可能存在问题?

任何帮助或想法将受到高度赞赏。

谢谢。

[更新]蒂姆解决了它! 非常感谢! – 还要感谢所有花时间试图解决这个问题的人:)

我想你是我从MSDN发现这篇文章有趣的: http : //msdn.microsoft.com/en-us/magazine/cc163413.aspx

文章说“Sys.WebForms.PageRequestManager.getInstance()。 add_pageLoaded (”也附加到Updatepanel完成事件。

每次代表UpdatePanel控件启动的异步回调完成并且UpdatePanel内的内容更新时,它也会触发。

然后在你的处理程序中,你可以循环使用更新的面板

 var panels = args.get_panelsUpdated(); for (i=0; i < panels.length; i++) { alert(panels[i]); } 

我会偏离使用_ postBackSettings,因为“_”表示隐私,可能会在未来版本的asp.net ajax中停止使用。

我已经使用ScriptManager上的ScriptMode =“Release”参数修复了jQuery / Updatepanels的各种异步问题。

    

AJAX和jQuery组合的一个常见问题是……

 $(document).ready(function() { buildDatepicker(); 

仅在第一页加载时发生。 如果替换受buildDatapicker()影响的HTML区域; 你丢失了附加在它上面的任何事件(即使你用相同的元素替换它)。

您需要做的就是针对新加载的HTML调用buildDatepicker …并传入已加载的元素,以确保您不会加倍…

 $(document).ready(function() { buildDatepicker(document); ... function buildDatepicker(element) { var dp = $("#datepicker", element).datepicker({ onSelect: function(dateText, inst) { /* Do a postback when someone clicks a date */ doAspNetPostback(); } }); } 

现在你可以调用buildDatepicker(myNewlyLoadedElement); 重新绑定数据选择器function。

您可以尝试使用datepicker设置altField并检查更改以执行回发。

我已经尝试过你的代码来重现错误,我可以重现错误。 我得出的结论是jQuery / UpdatePanels存在一些问题。

如果我用LinkBut​​ton替换该按钮,您可以看到链接直接调用__doPostBack(…),这与您调用的完全相同的参数完全相同。 并单击链接按钮直接工作,但单击日期不会。

所以这意味着在jQuery中发生了一些改变某些上下文的事情。 但我不知道会是什么。

我不久前发现了另一个剧本,我现在已经使用了一段时间,并且从未遇到任何问题。

   

您仍然可以像在上面的脚本中一样手动设置回调函数。

您可能还必须手动添加scriptresource处理程序(不记得哪一个)但我特别记得在调用异步和非异步回发时遇到问题。 希望有所帮助。

看起来像竞争条件,尝试UpdateMode =“Conditional”和ChildrenAsTriggers =“false”, 参考 。

但是,如果我在FireBug中逐步执行代码,那么它的工作原理就足够了

哦? 为什么不给它一点时间来解决它呢?

 setTimeout(function(){alert(sender._postBackSettings.panelID);},1000); 

我喜欢Tim的回答,围绕着你应该在pageLoaded事件中使用args.get_PanelsUpdated()的想法。 这似乎是做你试图做的事情的适当方法。 尝试一下 – 如果它不起作用,那么我的另一个想法就是我的袖子(尽管它有点脏)。

我觉得这很有意思,如果你在doPostBack之后添加一个警告,那么FF不会返回null。

  function doAspNetPostback() { __doPostBack('<%= hiddenOnSelectionChangedButton.ClientID %>', ''); alert('<%= hiddenOnSelectionChangedButton.ClientID %>'); }