ASP.NET組件設(shè)計(jì)Step by Step(6)
2024-07-10 13:03:53
供稿:網(wǎng)友
asp.net頁(yè)面如果是通過(guò)post請(qǐng)求到服務(wù)器,框架將會(huì)遵行事件周期生成、調(diào)用控件,而控件(如果支持回傳)則將加載回傳數(shù)據(jù),并且映射成控件的服務(wù)器端事件,就好像在重放客戶的客戶行為(客戶按下一個(gè)按鈕,卻引發(fā)服務(wù)器端控件的click事件)。其中的機(jī)制如何?
如果一個(gè)控件需要處理回傳事件,那么必須實(shí)現(xiàn)一個(gè)特定接口 ipostbackeventhandler接口:
public interface ipostbackeventhandler{
void raisepostbackevent(string eventargument);
}
以及另外一個(gè)接口:
ipostbackdatahandler
{
bool loadpostdata( string postdatakey, namevaluecollection postcollection);
void raisepostdatachangedevent();
}
一旦控件實(shí)現(xiàn)了這些接口,頁(yè)面框架就會(huì)自動(dòng)在postback數(shù)據(jù)完成后,調(diào)用控件的此接口ipostbackdatahandler。loadpostdata,從而讓控件讀取post上來(lái)的數(shù)據(jù)。postdatakey為postback數(shù)據(jù)中的命名鍵名,通過(guò)namevaluecollection[postdatakey]可以獲得頁(yè)面框架傳遞給控件的值。控件應(yīng)當(dāng)讀取此值,進(jìn)行自己內(nèi)部狀態(tài)更新,反映狀態(tài)變化。如果控件返回真,表示服務(wù)器控件狀態(tài)改變,此時(shí)頁(yè)面框架會(huì)立即調(diào)用此控件的raisepostdatachangedevent方法。此時(shí),控件應(yīng)當(dāng)自己定義該引發(fā)那些服務(wù)器控件對(duì)外提供的事件。這些事件往往是控件編程者精心設(shè)計(jì)留給使用這控鍵的aspx編程者的代碼舞臺(tái)。
至于另一個(gè)接口ipostbackeventhandler,也是回傳時(shí)候服務(wù)器調(diào)用的接口。我們知道每一個(gè)控件都有一個(gè)uniqueid,當(dāng)客戶端觸發(fā)一個(gè)可以引起回傳的客戶端事件(譬如按下了submit按鈕),那么自然http post數(shù)據(jù)到服務(wù)器端,服務(wù)器頁(yè)面框架進(jìn)行到postback處理時(shí)候,會(huì)檢索控件是否支持ipostbackeventhandler接口,并且查找控件的uniqueid發(fā)現(xiàn)支持就立即調(diào)用此接口的raisepostbackevent方法,表示uniqueid的控件發(fā)生了一個(gè)需要捕獲的事件。很明顯,并非客戶端所有事件都可以投射到服務(wù)器端,只能夠是能夠引發(fā)post back(也就是能夠提交表單數(shù)據(jù)到服務(wù)器的事件)的事件和控件。注意,這里嚴(yán)格要求了uniqueid必須在服務(wù)器端和客戶端對(duì)應(yīng)一致,否則無(wú)法映射事件。
值得控件編寫(xiě)者注意的是,如果要實(shí)現(xiàn)接口,需要如下實(shí)現(xiàn)接口,而不是通常的僅僅接口方法名同名即可:
void ipostbackeventhandler.raisepostbackevent(string eventargument)
{
……
}
也就是說(shuō),接口針對(duì)頁(yè)面框架實(shí)現(xiàn)的,也由頁(yè)面框架調(diào)用。
另一方面,在客戶端,能夠引起回傳的實(shí)際上僅有2個(gè)html元素<inoput type=submit >和<input type=image,但是通過(guò)客戶端腳本,其他客戶端事件也可導(dǎo)致回傳數(shù)據(jù)到服務(wù)器端。page類(lèi)提供了一系列的方法來(lái)幫助實(shí)現(xiàn)其他可引發(fā)回傳的途徑:
public string getpostbackclientevent(
control control,
string argument
);
獲取對(duì)客戶端腳本函數(shù)的引用,該函數(shù)在被調(diào)用時(shí)將導(dǎo)致服務(wù)器回發(fā)到窗體。
public string getpostbackclienthyperlink(
control control,
string argument
);將 javascript: 追加到從 getpostbackeventreference 調(diào)用的返回的開(kāi)頭,從而使服務(wù)器上可以進(jìn)行超級(jí)鏈接回發(fā)處理。
public string getpostbackeventreference(control);
public string getpostbackeventreference(control, string);
獲取對(duì)客戶端腳本函數(shù)的引用,調(diào)用該函數(shù)將使服務(wù)器
如果一個(gè)控件確定通過(guò)以上方法確保客戶端引發(fā)回傳事件,那么控件引用頁(yè)將導(dǎo)致最終輸出到客戶端的html中包含腳本,并且腳本中藏有如下隱含變量:
<input type=”hidden” name=”__eventtarget” value=””>
<input type=”hidden” name=”__eventargument” value=””>
<script language=”javascript”>
<!—
function __dopostback(eventtarget,eventargument)
{
var theform=document._ct10;
theform.__eventtarget.value= eventtarget;
theform.__eventargument.value= eventargument;
}
-- >
</script>
任何客戶端腳本只要合法調(diào)用了__dopostback方法即可實(shí)現(xiàn)回傳到服務(wù)器端,并且服務(wù)器端也知道了是引發(fā)了那一個(gè)uniqueid得控件的事件。
作者blog:http://blog.csdn.net/shanhe/