2009年2月12日 星期四

Ajax UpdatePannel注意事項

在 ASP.NET 2.0 預設實現 AJAX 有二種方式,一種是 CallBack 機制,另一種是 ASP.NET AJAX 的 UpdatePanel。只要是在 UpdatePanel 中的控制項,它需要在執行 AJAX 非同步更新時維護所有子控制項的狀態,所以需傳遞更多的資訊。如果沒有傳輸量的問題,UpdatePanel 無疑是實現 AJAX 的完美機制。[參考ASP.NET魔法學苑]。因為它讓畫面看起來不會Full PostBack,讓操作者感覺互動效果與使用一般應用程式相同。但是如果你在aspx頁面寫了JavaScript code要讓畫面onLoad時觸發執行,不論你是寫在body標籤的onLoad屬性或者寫成這樣:

<html>
<head>
<script type="text/javascript">
function alwaysDo( ) {
alert("hello!");
}

alwaysDo( );
</script>
</head>

<body>
.......
</body>
</html>

都只會讓alwaysDo()在第一次載入網頁時才會執行
之後的互動都不會觸發!
理由很簡單,因為畫面無Full PostBack所以瀏覽器始終存在第一次進來時的內容(HTML source code)
那如果這樣做呢?

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.ClientScript.RegisterStartupScript(GetType(Page), "", "alert('hello!');", True)
End Sub

看起來好像可以
因為RegisterStartupScript()就是在頁面註冊一段"當頁面載入後可立即執行的Script"
不過,遇到UpdatePannel還是沒輒
實際上,不論是RegisterStartupScript()或其他ClientScriptManager的Shared Method設計用意
是希望讓開發人員在後端"動態"加入Script到頁面中
當畫面載入瀏覽器後,我們用[檢視原始碼]的功能都可以看到被我們註冊的Script
但是,遇到UpdatePannel,因為頁面根本沒刷新
它回到後端後只是利用Ajax的CallBack技巧把要更改的內容置換掉
(雖然看起來畫面有變,實際上它的原始碼根本沒變,與第一次進來時相同!)
除非拿掉UpdatePannel,這樣頁面每次都可以"徹底"刷新,Script才有機會執行!
幸好,微軟發現這個問題了
在.Net Framework 2.0之後
只要有用到UpdatePannel的畫面
請用ScriptManager取代ClientScriptManager,例如:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ScriptManager.RegisterStartupScript(Me.Page,GetType(Page), "", "alert('hello!');", True)
End Sub

沒有留言: