從自己最常使用的功能說起。在網頁上放個 Button,壓下去後,跳出一個 alert 視窗,程式如下:
<form id="form1" runat="server">
<div>
<asp:button id="Button1" runat="server" onclick="Button1_Click" text="Button" />
</div>
</form>
以及 .cs 程式
protected void Button1_Click(object sender, EventArgs e)
{
ClientScript.RegisterStartupScript(this.GetType(), "JustAlert",
"<script> alert('Hello');</script>");
}
但當我將這個 button 移到 UpdatePanel 裡,就開始不正常了。我的 javascript 完全沒有反應,也沒有錯誤訊息。詳閱了「RegisterStartupScript Method (control, type, key, script, addScriptTags)」後,發現程式需要做些調整。該文章有提到,如果是在 UpdatePanel 裡,當我們使用了非同步更新的方法,要改用 ScriptManager 的 RegisterStartupScript,如下所示:protected void Button1_Click(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(this.Page, this.GetType(),
"JustAlert", "alert('Hello');", true);
}
既然在 UpdatePanel 裡需改用 ScriptManager 來呼叫 JavaScript,那理論上我在後端也可以呼叫前端所定義的 JavaScript 囉!所以,再試了一下:
/* .aspx */
<head runat="server">
<title></title>
<script>
function SayHi() {
alert('Hi');
}
</script>
</head>
/* .cs */
ScriptManager.RegisterStartupScript(this.Page, this.GetType(),
"JustAlert", "SayHi();", true);
果然可行。原來呼叫前端的 javascript 都沒問題,那是否也可以在 UpdatePanel 裡觸發整個頁面的 PostBack 呢?
ScriptManager.RegisterStartupScript(this.Page, this.GetType(),
"JustAlert", string.Format("__doPostBack('{0}','');", this.ClientID), true);
測試後,還蠻好用的,能夠順利的讓整個頁面都 PostBack。
這讓我想到一個情境。如果我的頁面很複雜很複雜,其中會有一個按鈕。當使用者按下這個按鈕後,會在後端先去做初步的判斷,決定是否要進一步去執行後續的動作,如果判斷沒必要繼續往後執行,則會在前端跳出訊息。但因為畫面很複雜很複雜(想像一下嘛,總有一天你會遇到),當被判斷沒必要往後執行時,也不希望造成整個頁面的 PostBack 而重載所有物件。
這情境下,我可以把確認按鈕,放到 UpdatePanel 裡面,並在 Button 事件裡,先去判斷是否有必要繼續往後執行。如果有必要,就會執行上面所說的,在 UpdatePanel 裡面觸發前端的 __doPostBack() 來達到頁面 PostBack 的效果。相反地,如果判斷沒有必要往後執行,則是透過 ScriptManager.RegisterStartupScript() 來產生前端 javascript 的 alert( ) 效果。
以下是測試的範例程式:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:Label ID="Label1" runat="server" Text=""></asp:Label>
<div>
<img src="https://encrypted-tbn2.google.com/images?q=tbn:ANd9GcSloWls9-zDJUF2RvunIn3-5zB8HJ-PTGJ3tc_jXIMJcbxBDvu7DQ" border="0"></img>
</div>
<asp:RadioButtonList ID="rbl" runat="server"
RepeatDirection="Horizontal">
<asp:ListItem Value="1">未滿18歲</asp:ListItem>
<asp:ListItem Value="2">滿 18 歲</asp:ListItem>
</asp:RadioButtonList>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="確認" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
public partial class ChangeMsgShow4 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//取得是誰觸發了 PostBack
string strTarget = "" + Request.Form["__EVENTTARGET"];
//判斷觸發 PostBack 的物件名稱是否為 MySpecial
if (strTarget == "MySpecial")
{
//執行自訂的後續執行方法
DoSpecial();
}
}
private void DoSpecial()
{
Label1.Text = "看蜘蛛人有這麼麻煩嗎?";
}
protected void Button1_Click(object sender, EventArgs e)
{
switch(rbl.SelectedValue)
{
case "1":
//判斷不需要繼續往後執行,所以只在前端 alert 一些訊息
ScriptManager.RegisterStartupScript(this.Page, this.GetType(),
"JustAlert", "alert('孩子,等待是值得的!');", true);
break;
case "2":
//判斷後有必要往後執行,所以在前端先跳出一段訊息後,接著觸發 __doPostBack,並
//把觸發 PostBack 的物件來源名稱設定為 MySpecial
ScriptManager.RegisterStartupScript(this.Page, this.GetType(),
"JustAlert", "alert('恭喜你已經成年!'); __doPostBack('MySpecial','');", true);
break;
default:
//判斷不需要繼續往後執行,所以只在前端 alert 一些訊息
ScriptManager.RegisterStartupScript(this.Page, this.GetType(),
"JustAlert", "alert('請摸著良心選擇!');", true);
break;
}
}
}
以前 Asp.Net 的前端與後端,總像是牛郎織女一樣,久久才會見面一次。但透過 Ajax 的技術,讓這兩人隨時都可以明來暗去,樂鬧許多。
參考:
01:RegisterStartupScript Method (control, type, key, script, addScriptTags)

沒有留言:
張貼留言