從自己最常使用的功能說起。在網頁上放個 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)
沒有留言:
張貼留言