2015年9月8日 星期二

入門與 PostBack觀念的練習

ASP.NET初學者 入門的觀念課

ASP.NET初學者要入門,有些觀念可能以前沒見過。

第一,以前寫過 ASP / PHP / JSP的朋友

在 ASP.NET裡面,會面對 Page的生命週期,例如:Page_Load事件與 IsPostBack(是否第一次執行?)。

為什麼按下 Button按鈕以後,Page_Load事件會重複被執行一次呢?

第二,最近在各論壇都有看見這個FAQ --

我想按下按鈕,每按一次,畫面上的數字就會累加(不斷地加一)

這是「狀態管理」,網頁程式的特色。以前寫過 Windows或是一般程式的人,會很陌生。



如果畫面上,不使用 Web控制項(如 TextBox或 Label)來存放 點擊(累加)的次數。

只允許您用 Response.Write()來呈現,那該怎麼作????



摘要:淺談 PostBack 機制

先在設計畫面拉出二個控制項:TextBox 與 Button
此時在網頁檢視原始碼,form 被轉譯為如下:

action 代表在 form 標籤內發出 submit 時所要導向的網頁,也就是自已本身網頁。


<form name="form1" method="post" action="Demo.aspx" id="form1">


此時button被轉譯如下:

就變成了 submit 功能的按鈕了。


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


所以當畫面上有 Button 控制項,點擊後會回貼本身網頁這稱為 PostBack 機制


當 TextBox 啟用 AutoPostBack 後就具備 PostBack 功能

此時 HTML 原始碼會多出一段 javascript ,TextBox 會被轉譯如下


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

<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
    theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
//]]>
</script>

<input name="TextBox1" type="text" onchange="javascript:setTimeout('__doPostBack(\'TextBox1\',\'\')', 0)" onkeypress="if (WebForm_TextBoxKeyHandler(event) == false) return false;" id="TextBox1" />



這時候有一個 onchange 的 JavaScript 事件,代表當 TextBox 的內容經過修改後就會引發。

引發事件時會去呼叫一個 JavaScript 函式 : __doPostBack(\'TextBox1\',\'\')

帶入有二個參數,第一個為引發此事件的表單之名稱,第二個為事件資訊


你會發現這個函式位於上方的 JavaScript 區塊,裡面做的事如下:

1. 取得網頁中的 form1 物件

2. 判斷是否 submit

3. 將傳進來的二個參數寫進最上方的二個隱藏欄位(hidden)

4. 發送 submit



此時就會發生 PostBack ,而此時在 ASP.NET 如何知道是由誰引發的事件呢?

就是靠之前所寫入的隱藏欄位(hidden)

ASP.NET 會使用 Request.Form["__EVENTTARGET"] 來知道事件是由誰所引發的


摘要:淺談 PostBack 機制(二)

並非任何控制項都具備 PostBack 功能

控制項必須實作 IPostBackEventHandler 介面才會具有 PostBack 功能

那該如何使沒有 PostBack 的控制項具有 PostBack 功能

例如 Label 控制項就不具備此功能,
使用 GetPostBackEventReference 方法


    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Label1.Attributes["onclick"] = 
                Page.ClientScript.GetPostBackEventReference(Label1, string.Empty);

            if (Request.Form["__EVENTTARGET"] == Label1.ID)
                Label1_OnClick();
        }

        private void Label1_OnClick()
        {
            Label1.Text = DateTime.Now.ToString();
        }
    }



有二個參數,第一個:將 PostBack 功能指定給控制項,第二個:指定事件參數

這時網頁原始碼如下

<span id="Label1" onclick="__doPostBack('Label1','')">Label</span>

所以也就是呼叫 JavaScript 的 __doPostBack 函式。


題外話:所以以此類推,要呼叫自訂的 JavaScript 函式也可以

Label1.Attributes["onclick"] = "myFunction()";