我试图了解一些关于使用更新面板的部分回发的信息,虽然很多事情都让我感到困惑,但这个让我感到困惑。
我在 UpdatePanel 中使用选项卡,因为这是一个数据输入应用程序,所以我将内容放入用户控件中,因此每个选项卡都有自己的用户控件。此外,我正在向每个用户控件添加自定义 javascript,以处理该控件中内容的特定客户端事务。
在这样做时,虽然我注意到用户控件中的 javascript 不会在部分页面回发时触发。
为了模拟这一点,我在 VS2010 中创建了一个非常简单的应用程序(在母版页上使用带有 ScriptManager 控件的母版页)。
默认页面的内容面板有以下内容
<asp:UpdatePanel runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:Button runat="server" ID="Button1" Text="Partial postback" />
<br />
<asp:Panel runat="server" ID="panel"></asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
然后我创建了一个用户控件并简单地添加了一些纯文本和一个 javascript 警报
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="UC1.ascx.vb" Inherits="TestWebApp_VB.UC1" %>
This is user control 1
<script> alert('control 1'); </script>
然后在内容页面的页面加载事件中,我将控件加载到面板中。
Panel.Controls.Add(LoadControl("UC1.ascx"))
此外,在按钮的单击处理程序上,我还加载了控件(或切换时的不同控件,如进一步所述)
Button_Click
Panel.Controls.Clear()
Panel.Controls.Add(LoadControl("SomeControl.ascx"))
因此,当页面第一次加载时,警报会触发,但是当您单击按钮并且页面被部分回发时,警报永远不会触发。
我向前迈了一步,创建了第二个用户控件,并让按钮切换加载控件,并在 UpdatePanel 之外添加了一个普通按钮。每当我进行完整回发时,加载的用户控件中的 javascript 都会触发,但它不会在部分回发时触发。
然后我向前迈了一步,将控件中的 javascript 移动到一个函数中,这样我就可以从 PageRequestManager 或 document.ready 调用该函数。
所以现在我的两个控件包含这个脚本(警报包含每个控件的不同消息)
<script type="text/javascript">
function userLoad() {
alert("Identify control");
}
</script>
因此,我将其添加到内容面板的末尾
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance().add_endRequest(userLoad);
</script>
好吧,现在每个部分回发都会触发 javascript,但是它会触发最后一次由完整回发加载的控件的 javascript。
例子:
- 页面最初加载 UserControl1 - UserControl1 的警报触发(此处未显示 - 在 jquery document.ready 中调用 userLoad 函数)
- 用户点击按钮 - 应该加载 UserControl2
- UserControl2 已加载到屏幕上,但会触发 UserControl1 的警报
有点罗嗦,为此道歉,我发现没有简单的方法来解释这一点。
- -编辑 - -
我尝试过的其中一件事是使用 Scotts 的建议。将每个控件的 javascript 保存在一个单独的文件中,并将其全部放入一个名为 function UC1Load() {} 之类的函数中(如果我觉得很活泼,可能会在它周围贴上一个命名空间),添加对脚本文件的引用内容页面通过
<script src='UC1.js'>
然后注册启动脚本来调用这个函数
ScriptManager.RegisterStartupScript(ctrl, ctrl.GetType(), "UserJS", "UC1Load()", True)
最大的问题是我现在必须下载一堆永远不会使用的脚本,这就是我首先将脚本放在用户控件中的原因。