top
Loading...
ASP.NET入門隨想之代言人
本報訊 著名品牌服務器控件(Control)攜手奧運冠軍客戶端HTML標簽作為形象代言人,新形象以"極速體驗"為主題,既詮釋了服務器控件本身強大的信息處理能力,也表現客戶端HTML標簽希望用靈動和親切來證明自己的決心與態度。

■ 內與外 - property與attribute

近日Google發布除英文外的唯一名稱--谷歌,中國用戶一片嘩然, 暫且不論這個谷歌是不是比胡弋更合適,但Google想借此闡述產品內涵,取悅中國用戶之心路人皆知;今年WEB2.0引無數風投競折腰,40億美金撒向大陸都是錢,于是網站們如同川劇變臉,搖身一變,換成一張張博客、書簽、圈圈的面龐。冷靜思考,在信息過剩,特別是同質化嚴重的前提下,數據挖掘、用戶體驗成為網站關鍵,有人戲稱三分長相(內容),七分打扮(內容聚集和用戶體驗)。即是如此,人機交互設計從可有可無提升到必不可少、Ajax技術變火也就不奇怪了。

服務器端處理總是WEB應用系統的核心功能,大多數的信息處理在服務器端完成。但如果把所有功能都放在服務器端,讓頁面帶著幾百幾千字節的ViewState在網絡中來回穿梭,那可不是惡心,那是相當的惡心。所以我們需要客戶端充當服務器端的代言人,通過執行腳本程序來分擔一些系統功能,讓用戶更爽,讓服務器更輕松。

ASP.NET通過控件與用戶完成交互,但就客戶端瀏覽器而言,它從未聽過,也不和控件打交道,它所熟悉的是HTML標簽和客戶端腳本程序。要讓客戶端充當服務器端的代言人,就必須讓二者交流與溝通,即:動態添加客戶端行為、動態生成客戶端腳本、控件行為與客戶端行為映射等。

attribute和property是一對有趣的近義詞,MSDN中有這么一句話:"在 ASP.NET 服務器控件的標記中,可以使用屬性 (attribute) 來設置屬性 (property) 值。"屬性設置屬性?頭暈目眩中。簡單地理解,property是類的成員,attribute是類的外觀。前者是品牌自身特征,后者為代言人特征,前者可以通過后者來展示自己。反映到控件與對應HTML標簽,控件狀態是property,標簽中對應的字符串是attribute,即瀏覽器所看到的服務器端控件的外形。

■ 宣布 - 添加客戶端行為

HTTP響應流就是一串字符流,頁面生成一個HtmlTextWriter實例,專門收集控件們生成的HTML標記文本,它按控件樹的次序,讓控件的RenderControl方法檢查自己的Visible屬性,如果為真就調用控件的Render方法向實例添加標記文本,搞定后調用RenderChildren方法向下遞歸傳遞。所以在頁面調用控件Render方法之時或之前,可以在動態地修改標簽中的Attribute以組裝成相應的標記文本。

向控件添加客戶端行為,最簡單的方法是在.apsx文件中的標簽直接聲明對應的Attribute,或以編程方式調用控件Attributes 集合的Add方法,即向客戶端瀏覽器宣布:我的代言人是老徐''

<%@ Page Language="C#" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e){
// 為btnTest控件添加onmouseover和onmouseout客戶端行為
btnTest.Attributes.Add("onmouseover","MakeRed();");
btnTest.Attributes.Add("onmouseout","RestoreColor();");
}
</script>
<html><head runat="server">
<script language="javascript">
var previousColor;
// 改變前景色
function MakeRed(){
previousColor = window.event.srcElement.style.color;
window.event.srcElement.style.color = "#FF0000";
}
// 恢復原前景色
function RestoreColor(){
window.event.srcElement.style.color = previousColor;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:button id="btnTest" text="btnTest" runat="server" />
</form>
</body></html>

■ 注入 - 動態添加客戶端腳本

除了直接在.aspx文件中顯式聲明外,Page類還提供了一些方法用于動態創建客戶端腳本。所謂的動態生成腳本,實際上就是生成對應的腳本字符串,然后使用Page類提供的RegisterClientScriptBlock 、RegisterOnSubmitStatement等方法注入到HtmlTextWriter實例中合適的位置,同時,ASP.NET還提供若干方法用于輔助生成腳本,無非就是加點隱藏輸入域、數組之類的東西。

控件也可以在OnPreRender方法調用這些方法通知頁面添加所需腳本字符串。之所以不在Render方法中實現,是因為HtmlTextWriter實例在被傳遞到控件手上時,Page類已經完成在HtmlTextWrite實例中生成對應文本,慢了一步。下例為頁面回發添加一個確定對話框。

<%@ Page Language="C#" %>
<script runat="server">
protected void Page_Load(Object sender, EventArgs e){
String scriptText = "return confirm('要提交嗎?')";
//添加頁面提交時執行的腳本。 RegisterOnSubmitStatement("ConfirmSubmit", scriptText);
}
</script>
<html><head></head><body>
<form id="form1" runat="server">
<asp:button id=btnTest text=PostBack runat="server" />
</form></body></html>

■ 攜手 - GetPostBackEventReference方法

很多時候我們希望客戶端行為能夠和相應的服務端行為攜起手來,共同完成一個完整的系統功能,即客戶端行為能夠觸發相應的服務器端行為,即兩者映射。在ASP.NET1.1中,本質上是把頁面為原子回發單位,客戶端行為只能在頁面回發之前向隱藏標志域里寫入帶有自身特征的數據,頁面回發后,控件們通過檢查隱藏標志域的數據來觸發相應的行為。

客戶端與服務端攜手典型例子有兩個:一是GetPostBackEventReference方法,它可以引發帶有特征數據的頁面回傳;一是大名鼎鼎的驗證器構架,除此之外,標準控件也有若干是通過客戶端行為來實現。下面我們以前者為例,演示完整的"生成-客戶端處理-回發-服務端處理"過程。

public class MyControl : Control, IPostBackEventHandler{
//定義Number屬性
public int Number{
get{
if ( ViewState["Number"] !=null )
return (int) ViewState["Number"];
else
return 50;
}
set { ViewState["Number"] = value; }
}
//依賴于用戶操作的事件處理,請參考《隨想十一》
// eventArgument為事件數據,這里由GetPostBackEventReference設置
public void RaisePostBackEvent(string eventArgument){
if ( eventArgument == "inc" ) Number ++;
if ( eventArgument == "dec" ) Number --;
}
//生成控件對應的HTML標記文本
//除生成Number屬性文本外,還生成兩個引發回發并帶著回發事件參數的超鏈接
// GetPostBackEventReference 方法發出啟動回發的客戶端腳本,并提供引用
protected override void Render(HtmlTextWriter writer){
writer.Write("控件值:" + Number.ToString() + " " );
writer.Write("<a href="javascript:" + Page.GetPostBackEventReference(this,"inc") + "">+</a>");
writer.Write(" or ");
writer.Write("<a href="javascript:" + Page.GetPostBackEventReference(this,"dec") + "">-</a>");
}
}

由于ASP.NET1.1是以頁面為原子回發單位,代言人與品牌之間的溝通和聯系要付出巨大的性能代價。要改善只能打破以頁面作為原子回發單位的制度。




作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗