通过 AJAX (ASP.NET 2.0) 在子窗口关闭时部分更新父页面 - 有条件地






4.74/5 (43投票s)
基于从子窗口通过 AJAX(使用 UpdatePanel)传递的特定值部分更新父页面。
引言
有时,我们需要打开一个子窗口,在其中进行一些操作,然后关闭它。现在,根据在子窗口中执行的操作,我们可能需要刷新父页面,也可能不需要。现在,不仅仅是刷新,而是**部分刷新**!我试图演示如何将一个值传递给子窗口,在那里进行一些操作,然后在保存时,我们部分更新父页面。如果在子窗口中没有进行任何操作或者操作被取消,那么就不会更新父页面。整个操作给用户一种良好的感觉,并且页面的性能看起来会好很多。
背景
在我们的项目中,我们有一个需求,需要基于从子窗口返回的特定值来部分更新父页面。 早期,我们能够更新父页面,但是每次都会更新! 最终,在找到下面描述的方法之后,我们才能够仅在需要时才实现父页面的部分更新。
使用代码
为了演示,我在父页面上放置了一些 Label
。其中一些在 UpdatePanel
内部,一个在外部 - 只是为了观察页面何时进行部分更新。 父页面的 ASPX 看起来像
<form id="form1" runat="server">
<asp:ScriptManager ID="smParent" runat="server" />
<div id="divUpdatePanel">
<asp:UpdatePanel ID="upParent" runat="server">
<ContentTemplate>
<asp:Label ID="lblCurrTime" runat="server" Text="CurrTime:">
</asp:Label> <br />
<asp:Label ID="lblChildWinValue" runat="server"
Text="ChildWin Value:"></asp:Label><br />
<br /><a href="javascript:OpenChildWindow();">
Click to open the Child Window</a><br />
<input type="button" id="btnHiddenForUpdate"
runat="server" style="display:none"
onserverclick="btnHiddenForUpdate_ServerClick" />
<br />
</ContentTemplate>
</asp:UpdatePanel>
</div>
<div id="divNormalUpdatePanel">
<asp:Panel ID="pnlFullPostback" runat="server">
<asp:Label ID="lblPageLoadTime" runat="server"
Text="PageLoadTime:"></asp:Label>
</asp:Panel>
</div>
</form>
我们可以使用任何控件打开一个子窗口。在这个项目中,我使用了一个 "<a href
" 链接。 会打开一个模态对话框,并将一个虚拟值作为查询字符串传递(如果需要)。 在下面的脚本中,捕获返回的值,并根据返回的值触发部分更新。 这是打开对话框窗口的脚本
<script type="text/javascript">
function OpenChildWindow()
{
//open a new dialog window
var sFeatures="dialogHeight: 200px;";
sFeatures += "dialogWidth: 400px;";
sFeatures += "center: yes;";
sFeatures += "edge: sunken;";
sFeatures += "scroll: no;";
sFeatures += "status: yes;";
sFeatures += "resizeable: no;";
var url = 'ChildForm.aspx?SomeValue=12345';
entryWindow=window.showModalDialog(url, 'ChildForm', sFeatures);
if(entryWindow ==true)
{
alert("Watch for CurrTime & ChildWin labels," +
" its going to update as new window saved.");
//this would trigger the update panels
//update as the button is part of the UP
window.document.getElementById('btnHiddenForUpdate').click();
}
else
{
//No change will happen to the parent page as child page did nothing
alert("Nothing on the page will change " +
"as the new child window was cancelled.");
}
}
</script>
进入新的子窗口后,我们可以在此处执行所需的操作。 操作完成后,我们可以保存它并继续前进,或者如果我们需要取消,我们可以选择“取消”按钮。 在示例项目中,保存并继续表单时传递布尔值“true”,而在取消时传递“false”。
<script type="text/javascript">
function WindowClose()
{
//return some value from here based
//on which Parent will decide the partial update
window.returnValue = true;
window.close();
}
function WindowCancel()
{
//return some value from here based on which
//Parent will decide the partial update
window.returnValue = false;
window.close();
}
</script>
父窗口根据从子窗口返回的值,决定是否激活放置在 UpdatePanel
中的虚拟按钮,以触发部分更新。 我们将按钮的“display
”样式保持为“hidden
”,这样就不会影响 UI,但是我们使用它来按需触发 UpdatePanel
。 按钮单击是在 JavaScript 中触发的,它完成了这项工作。
if(entryWindow ==true)
{
alert("Watch for CurrTime & ChildWin labels, " +
"its going to update since the new child window saved something");
//this would trigger the update panels update as the button is part of the UP
window.document.getElementById('btnHiddenForUpdate').click();
}
else
{
//No change will happen to the parent page as child page did nothing
alert("Nothing on the page will change " +
"as the new child window was cancelled");
}
现在,可以在服务器端以适合开发人员的方式处理更新。 在示例中,我在隐藏按钮的服务器端事件方法中更新控件。
protected void btnHiddenForUpdate_ServerClick(object sender, EventArgs e)
{
//Update Panels update - repopulate the controls the way needed.
lblChildWinValue.Text = "ChildWin Value: " + "SOME VALUE";
lblCurrTime.Text = "CurrTime: " + DateTime.Now.ToString();
lblChildWinValue.BackColor = Color.Yellow;
lblCurrTime.BackColor = Color.Yellow;
//Just to show that this label wont update as outside the update panel
lblPageLoadTime.Text = "PageLoadTime: " + DateTime.Now.ToString();
lblPageLoadTime.BackColor = Color.Yellow;
}
因此,使用 JavaScript 和 ASP.NET2.0 UpdatePanel
,我们仅在满足特定条件时才实现了父页面的部分更新。
关注点
基本的技巧是使用 UpdatePanel
中的虚拟隐藏按钮来触发更新。 代码的性能看起来不错。