細(xì)節(jié)決定成敗 ASP.NET中的蝴蝶效應(yīng)
2006/11/30 10:01:41
前言
ASP.NET的優(yōu)點(diǎn)我說(shuō)過(guò)很多次了,也就是各個(gè)控件獨(dú)立負(fù)責(zé)自己內(nèi)部的邏輯,這是一個(gè)好事情,因?yàn)樗鉀Q了原本ASP處理邏輯耦合度高的問(wèn)題。然而這是需要代價(jià)的,那就是引入ASP.NET頁(yè)面生命周期,隨著控件的多層嵌套,應(yīng)用的復(fù)雜度增加,我們?cè)俅蜗萑肽嗵?
問(wèn)題
其實(shí)這個(gè)文章題目我兩個(gè)月前就寫下了,可是一直沒(méi)想寫完它,直到今天我在這個(gè)泥潭中泡了幾個(gè)小時(shí),于是決定先從泥潭中跳出來(lái)把文章寫完,再跳進(jìn)去繼續(xù)解決問(wèn)題。問(wèn)題是這樣的:
使用MS AJAX 1.0 Beta2 + 2.0 CTP新建一個(gè)項(xiàng)目,同時(shí)在Bin中放上Beta2的AjaxControlToolkit.dll。
扔上一個(gè)Accordion,放置幾個(gè)AccordionPane,設(shè)置一下CssClass。
在Page_Load中使用Page.LoadControl加載一個(gè)UserControl,然后添加到頁(yè)面上。
接著發(fā)現(xiàn)UserControl內(nèi)的控件無(wú)法正常觸發(fā)事件,陷入泥潭中……
首先要說(shuō)明,如果僅僅做第3步那個(gè)UserControl肯定正常運(yùn)作,那意味著問(wèn)題出在ScriptManager或Accordion中出現(xiàn)了問(wèn)題。
正文
想知道到底是什么出問(wèn)題了嗎?先聽(tīng)我說(shuō)說(shuō)這個(gè)ASP.NET頁(yè)面生命周期的問(wèn)題吧。
由于生命周期按階段劃分,任務(wù)在不同階段按部就班完成,所以我們的每一個(gè)操作都是階段相關(guān)的,有些操作僅能在特定的階段操作,有些操作在不同階段執(zhí)行會(huì)導(dǎo)致不同的結(jié)果。當(dāng)然,MS希望盡量消除這些階段間的差異,例如讓一個(gè)操作在盡可能多的階段中都能執(zhí)行,并且盡可能減少在不同階段中操作引發(fā)的不同結(jié)果。然而這不可能完全做到,例如我們都知道ViewState讀寫限制為僅能在某些階段進(jìn)行,于是依賴于ViewState的控件屬性也就因此受到同樣的限制。
控件屬性讀寫受階段限制,這很好接受,對(duì)吧?因?yàn)檫@僅僅是一層依賴關(guān)系。順著依賴關(guān)系推廣出去,情況會(huì)變得越來(lái)越復(fù)雜,限制的原因埋藏得越來(lái)越底層,接著我們發(fā)現(xiàn)復(fù)雜性這一問(wèn)題在ASP.NET這種結(jié)構(gòu)良好的體系中出現(xiàn)了,而消滅這種復(fù)雜性的銀彈還沒(méi)被發(fā)明。
作為控件或組件的開(kāi)發(fā)人員,我們當(dāng)然有義務(wù)消除階段差異,讓下游的開(kāi)發(fā)人員面對(duì)更低的復(fù)雜性,而且我們也確實(shí)盡力去做了。控件的每一層封裝,都包含著這種努力,并向上承諾盡可能低的階段差異。然而為了讓控件看起來(lái)簡(jiǎn)單易用,我們不可能將這些差異完整地記錄在文檔之中,我們嘗試去隱瞞細(xì)節(jié),控件被層層封裝時(shí)我們都這樣做。底層文檔沒(méi)告訴我的差異,我當(dāng)然也沒(méi)必要寫到這一層的文檔上去;底層文檔提及了的差異,我盡力彌補(bǔ)了,即使彌補(bǔ)得不太好,也不寫到這一層的文檔上去。于是文檔就好像神話傳說(shuō)一樣隨著世代相傳而改變,最終沒(méi)有人知道這個(gè)控件依賴于某些底層的階段差異。
做過(guò)控件開(kāi)發(fā)的人都知道,有時(shí)候我們必須根據(jù)實(shí)際情況采用不同的方式構(gòu)建看起來(lái)一樣的控件。例如最簡(jiǎn)單的數(shù)據(jù)控件都會(huì)存在是否PostBack的構(gòu)建差異,如果是非PostBack,則需要在DataBind時(shí)構(gòu)建并將數(shù)據(jù)保存到ViewState,如果是PostBack則根據(jù)ViewState直接構(gòu)建,如果PostBack后又遇到了DataBind則需要清除原來(lái)的構(gòu)建并重新根據(jù)新數(shù)據(jù)構(gòu)建。再?gòu)?fù)雜一些的控件,還會(huì)分步驟構(gòu)建,默認(rèn)情況下為了消除使用方的階段差異,部分構(gòu)建步驟會(huì)盡可能靠前到Init時(shí)執(zhí)行,而另外一部分構(gòu)建步驟則盡可能推遲到PreRender時(shí)執(zhí)行,中間部分則盡可能減少自己的變化以便使用方操作。然而事情不會(huì)那么簡(jiǎn)單,使用方的某些操作(通常是訪問(wèn)某個(gè)屬性)如果依賴于某個(gè)構(gòu)建步驟的完成,因此一旦這些操作出現(xiàn),原本在PreRender才執(zhí)行的特定構(gòu)建步驟就要提前執(zhí)行,當(dāng)這樣的操作在不同階段進(jìn)行多幾次,構(gòu)建步驟就已經(jīng)散落在頁(yè)面生命周期的各階段。
構(gòu)建步驟可能散落于頁(yè)面生命周期的各階段對(duì)于控件設(shè)計(jì)師來(lái)說(shuō)是一個(gè)嚴(yán)峻的問(wèn)題,這意味著他要保證任何一個(gè)構(gòu)建
下一頁(yè)
返回列表
返回首頁(yè)
主站蜘蛛池模板:
中文字幕精品无码亚洲字|
伊人久久大香线蕉综合影院首页|
在线天堂av影院|
少妇人妻在线视频|
久久伊人精品一区二区三区|
欧美性色19p|
人妻无码久久久久久久久久久|
色五五月五月开|
国产寡妇树林野战在线播放|
**aaaaa毛片免费同男同女|
夭天曰天天躁天天摸在线观看
|
久久久无码人妻精品无码|
欧美另类69xxxxxhd|
亚洲色中文字幕在线播放|
精品无码成人片一区二区98
|
免费乱理伦在线播放|
老鸭窝laoyawo国产精品|
国产成 人 综合 亚洲专|
你懂的视频在线播放|
国农村精品国产自线拍|
www.日韩av.com|
成全高清视频免费观看|
久久人人爽人人爽人人片av高请|
欧洲精品久久久AV无码电影|
亚洲欧美日韩一区在线观看|
琴帝type=小说|
再深点灬舒服了灬太大了乡村|
色人阁在线视频|
国产交换丝雨巅峰|
黄色软件下载免费观看|
国产精品一区12P|
456在线视频|
国语自产精品视频在线看|
eeuss影院在线奇兵区1页|
强行扒开双腿猛烈进入|
中文字幕在线观看一区二区
|
亚洲成av人片在线观看无码不卡
|
va天堂va亚洲va影视中文字幕|
成人午夜性a级毛片免费|
中文字幕永久视频|
日日摸日日碰夜夜爽亚洲|