2009年3月16日 星期一

為什麼我的 Button 沒有呼叫 __doPostBack

一如往常所見,檢視網頁原始碼時,可以找到 __doPostBack 的 JavaScript 宣告。同時包含著兩個 hidden 欄位的宣告: __EVENTTARGET, __EVENTARGUMENT。


<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />

function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}

__EVENTTARGET 用來儲存是誰觸發了 PostBack。
__EVENTARGUMENT 則是用來儲存這次的 PostBack 是否有其它參數須一併傳遞。

以 DropDownList 為例,在網頁放置一個 DropDownList 後,它的原始碼變為

<select name="DropDownList1" onchange="javascript:setTimeout('__doPostBack(\'DropDownList1\',\'\')', 0)" id="DropDownList1">
<option value="A">A</option>
<option value="B">B</option>
</select>

當你的 DropDownList 的挑選項目被更動之後,就會觸發__doPostBack( )。eventTarget指的是造成發生PostBack的控制項是誰?而 eventArgument則是觸發PostBack同時,是否有其他參數需要傳遞。
在範例中,當發生PostBack時,就可以知道造成PostBack的就是 DropDownList1 ,而此次並沒有其他參數傳遞,所以是空字串。__doPostBack( ) 此時會將2個隱藏欄位(__EVENTTARGET,__EVENTARGUMENT)作一次更新後再將本頁面送出(Submit)。透過這種機制,送出後新載入的頁面,就可以透過
string strTarget = ""+Request.Form["__EVENTTARGET"];
來取得觸發PostBack的物件是誰了。
 

然而,這種機制並不適合 ButtonImageButton 兩個控制項。
現在再拉一個Button控制項並檢視它的原始碼。

<input type="submit" name="Button1" value="WebControl" id="Button1" />

可以看到Button的原始碼並沒有去呼叫__doPostBack( )。而先前提到的兩個隱藏欄位 __EVENTTARGET,__EVENTARGUMENT 也就不會被更新,當頁面送出後,還可以透過 Request.Form["__EVENTTARGET"] 去抓到觸發 PostBack 的控制項是誰嗎?試著測試一下,您會發現得到的是空白。所以,為何 Bubbon 或 ImageButton 在 PostBack 之後的頁面無法透過 Request.Form["__EVENTTARGET"] 抓到值,主要是它產生的程式碼裡並非透過 __doPostBack( )來實作,也沒有留下紀錄到 __EVENTTARGET 隱藏欄位裡頭,所以才會抓不到資料。
 

雖然 Button 或 ImageButton 沒有辦法讓送出後的頁面抓到 __EVENTTARGET 的值,但可以有其他的選擇。捨棄 Sever Control 改用 Html Control。在 VS(Visual Studio) 的工具箱裡,選擇 HTML 的群組,拉一個 HTML Button 控制項出來,同時將這個控制項的屬性設定為【以伺服器控制項執行】(其實就是設定 runat="server"),接著在 HTML Button 快點兩下,以產生 onserverclick 事件。做完這些動作後,檢視程式碼可以發現如下的改變:

<input language="javascript" onclick="__doPostBack('IamHtmlButton','')" name="IamHtmlButton" type="button" id="IamHtmlButton" value="HtmlControlinServer" />

這個HTML Button 使用了 __doPostBack( ) ,不意外的,我們可以在送出後的頁面抓到 __EVENTTARGET 裡面所記錄的值,就是這個 HTML Button。
 

參考資料:
[1]Understanding the JavaScript __doPostBack Function
[2]藍色小舖

沒有留言:

張貼留言