閱讀本文之前,您需要安裝完成Microsoft ASP.NET AJAX v1.0 Beta(詳見擁抱變化——從Atlas到ASP.NET AJAX(1):下載安裝總覽)。安裝完成之后,Visual Studio中新建Web Site的時候會多出一個模版:ASP.NET AJAX Enabled Web Site。接下來的內容均將基于新建的ASP.NET AJAX Enabled Web Site。
?
摘要
在ASP.NET AJAX中,Extender Control(擴展器控件)同樣很重要。如果說UpdatePanel只是將Ajax的核心概念和基本特性——局部更新和異步回送引入了ASP.NET的話,那么擴展器控件則在這個基本特性上邁出了新的一步——為頁面添加豐富的客戶端功能,讓用戶一眼就能夠看出來:噢,這個網站真的太“Ajax”了!
本文將分析相對于從Atlas到ASP.NET AJAX中擴展器控件使用方法的變化。
?
擴展器控件介紹
ASP.NET AJAX提供了兩種內建的擴展器控件:DragOverlayExtender和AutoCompleteExtender,前者讓用戶可以將頁面中的某個部分在其中任意拖動并排布,而后者可以為某個TextBox添加自動完成的功能。這樣,該TextBox將擁有類似瀏覽器地址欄的行為,用戶輸入一段文字后會自動彈出與之匹配的提示選項。關于CTP版本的AutoCompleteExtender使用方法,請參考使用ASP.NET Atlas AutoComplete Behavior或AutoComplete Extender實現自動完成功能(上)以及使用ASP.NET Atlas AutoComplete Behavior或AutoComplete Extender實現自動完成功能(下)。
擴展器控件的實現原理也不復雜:ASP.NET AJAX將在生成HTML時將ASP.NET頁面中定義的擴展器控件轉化為ASP.NET AJAX客戶端行為(Behavior)的聲明,并添加到頁面中,除此之外的所有實現均由ASP.NET AJAX的客戶端運行時處理。當頁面到達客戶端之后,客戶端的ASP.NET AJAX框架將在客戶端運行該行為。關于ASP.NET AJAX客戶端行為,請參考在ASP.NET Atlas中創建自定義的Behavior(注意,該文章基于CTP版本書寫,部分內容已經過時)。
另一個微軟公司和社區共同開發的免費開源的第三方控件包——ASP.NET AJAX Control Toolkit則提供了更多、甚至可謂包羅萬象的擴展器控件,幾乎覆蓋了常用的各種富客戶端功能,并且還在迅速增加中。而這些控件使用起來又和ASP.NET AJAX內建的擴展器控件完全一致,讓開發人員倍感親切。ASP.NET AJAX Control Toolkit中提供的這些擴展器控件將在本卷第7、8、9、10章中詳細介紹。ASP.NET AJAX Control Toolkit還提供了擴展器控件的基礎開發設施(控件基類等)以及Visual Studio中的項目模版等。借助于這些便利的設施,我們也可以容易地進行自定義控件的開發。關于服務器端擴展器控件的開發,請參考開發ASP.NET Atlas服務器端Extender控件——基本概念以及預先需求、開發ASP.NET Atlas服務器端Extender控件——編寫客戶端Behavior、開發ASP.NET Atlas服務器端Extender控件——編寫服務器端Extender & Dflying近期動向以及開發ASP.NET Atlas服務器端Extender控件——在實際開發中使用編寫好的控件(注意,該文章基于CTP版本書寫,部分內容已經過時)。
?
CTP版本的擴展器控件使用方法
一般來講,我們可以采用如下方法使用CTP版本中的擴展器控件:
在將要應用擴展器控件的頁面上要保證有一個ScriptManager控件,并且其EnableScriptComponents屬性值要設定為true(這也是其默認值)。因為擴展器控件將生成Atlas的客戶端行為(Behavior),然后委托給這個行為去完成真正的客戶端擴展工作,而行為的運行則需要有完整的Atlas客戶端框架支持。 頁面源代碼中,在ScriptManager控件聲明的后面添加擴展器控件的聲明。即添加類似<atlas:[擴展器名稱]Extender>的標簽,并為其指派一個ID,當然還有必不可少的runat="server"。這個標簽可以被認為是該Atlas頁面中所有同樣類型的擴展器控件的歸類。你同樣可以在該標簽中指定擴展器的某些屬性,和AutoCompleteExtender擴展器的MinimumPrefixLength、ServiceMethod、ServicePath等屬性一樣。 在擴展器控件的聲明標簽內添加擴展其屬性聲明標簽,即在<atlas:[擴展器名稱]Extender>標簽內添加類似<atlas:[擴展器名稱]Properties>標簽。該擴展器的擴展目標(TargetControlID屬性,這是每一種<atlas:[擴展器名稱]Properties>標簽都支持的。)以及其專有的屬性(例如<atlas:AutoCompleteProperties>的Enabled屬性)可以在該標簽中設定。 對于<atlas:[擴展器名稱]Properties>標簽和<atlas:[擴展器名稱]Extender>標簽中暴露出的相同的屬性,我們可以任選一處進行設定。但如果兩處都設定了的話,那么將取<atlas:[擴展器名稱]Properties>標簽中的設定值,也就是說<atlas:[擴展器名稱]Properties>標簽中的設定將覆蓋<atlas:[擴展器名稱]Extender>標簽中的設定。合理選擇某個重復出現在<atlas:[擴展器名稱]Properties>標簽和<atlas:[擴展器名稱]Extender>標簽中屬性的設定位置將有利于在頁面中包含有多個同樣類型擴展器控件時減少擴展器聲明部分的代碼量。 一個<atlas:[擴展器名稱]Extender>標簽下可以定義多個<atlas:[擴展器名稱]Properties>標簽。換句話說,若要使用已經在頁面中使用過的擴展器控件,我們既可以重新添加一個<atlas:[擴展器名稱]Extender>標簽并在其中添加相應的<atlas:[擴展器名稱]Properties>標簽,也可以在原有的<atlas:[擴展器名稱]Extender>標簽內添加一個新的<atlas:[擴展器名稱]Properties>標簽。一般情況下,我們應該盡力使用后一種方法,因為這樣可以讓代碼簡潔易懂。然而,不是所有的擴展器控件,也不是在每種情況下我們都可以使用這種方法的,某個擴展器控件是否能夠完全支持這種只添加另一個額外<atlas:[擴展器名稱]Properties>標簽的方法來在頁面中添加多個擴展器,將取決于控件設計時<atlas:[擴展器名稱]Properties>標簽中所暴露出的屬性能否完全覆蓋<atlas:[擴展器名稱]Extender>標簽中暴露的屬性。 一個現有的ASP.NET控件可以添加多個擴展器控件,分別使用不同的<atlas:[擴展器名稱]Extender>標簽聲明。 ?
CTP到Beta中擴展器控件使用方法的變化
Beta版本中,ASP.NET AJAX的擴展器控件概念被大大簡化,取消了CTP版本中的<atlas:[擴展器名稱]Extender>和<atlas:[擴展器名稱]Properties>這兩個標簽,而是統一使用<asp:[擴展器名稱]Extender>標簽。所有的屬性也都在<asp:[擴展器名稱]Extender>標簽中設置。
?
Beta版本的擴展器控件使用方法
一般來講,我們可以采用如下方法使用Beta版本中的擴展器控件(同樣適用于ASP.NET AJAX Control Toolkit中的擴展器控件):
在將要應用擴展器控件的頁面上要保證有一個ScriptManager控件。因為擴展器控件將生成ASP.NET AJAX的客戶端行為,然后委托給這個行為去完成真正的客戶端擴展工作,而行為的運行則需要有完整的ASP.NET AJAX客戶端框架支持。 頁面源代碼中,在ScriptManager控件聲明的后面添加擴展器控件的聲明。即添加類似<asp:[擴展器名稱]Extender>的標簽,并為其指派一個ID,當然還有必不可少的runat="server"。 該擴展器的擴展目標控件(由TargetControlID屬性指定)是必不可少的,任何一種擴展器控件都支持該屬性。我們應該將其指向需要被“擴展”的服務器端控件,例如上面的AutoCompleteExtender示例程序中就將該屬性指向了頁面中的一個TextBox。 設置該擴展器控件專有的屬性,例如AutoCompleteExtender的ServicePath和ServiceMethod屬性等。 我們可以為某個現有的ASP.NET控件添加多個擴展器控件,這些功能將疊加到一起,并應用到目標控件上。 ?
擴展器控件與裝飾模式(Decorator Pattern)
ASP.NET AJAX中的擴展器控件是裝飾模式的一次非常典型且完美的應用。Design Pattern一書中提到,裝飾模式有如下的幾種使用情況:
在不影響其他對象的情況下,以動態、透明的方式給單個對象添加職責。 處理那些可以撤消的職責。 當不能采用生成子類的方法進行擴充時。一種情況是,可能有大量獨立的擴展,為支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增長。另一種情況可能是因為類定義被隱藏,或類定義不能用于生成子類。 對于這三種使用情況,ASP.NET AJAX中的擴展器控件均有良好體現。我們就以應用于ASP.NET中TextBox控件的AutoCompleteExtender擴展器控件來舉例:
不是應用程序中所有的TextBox都需要自動完成功能的。一般來講,需要自動完成功能的TextBox在整個應用程序中所占的比例非常少。若使用繼承來實現該功能,則勢必導致自動完成功能在大多數TextBox中都沒有使用。而且,這種繼承的實現方式也需要對現有的代碼進行修改(將<asp:TextBox>標簽修改為類似<asp:AutoCompleteTextBox>的標簽)。既提高了對現有程序擴展的難度,也增大了在修改過程中發生錯誤的可能性。 對于程序中需要暫時控制自動完成功能啟用與否的需求,我們只要簡單地改變是否為其添加AutoCompleteExtender擴展器控件既可。若采用繼承的方式在程序中動態創建新的TextBox,則需要選擇不同的對象(TextBox或AutoCompleteTextBox)進行創建,比較麻煩;而若采用應用了裝飾模式的擴展器控件方式,就可以首先總是創建同一類TextBox控件,然后根據是否需要自動完成功能來決定是否創建AutoCompleteExtender。即使程序運行中該TextBox不再需要自動完成功能了,我們也無需對TextBox做任何的修改,只要移除其附加的AutoCompleteExtender即可。 對于ASP.NET的TextBox控件來說,我們既可以使用AutoCompleteExtender讓其擁有自動完成的功能,也可以使用ASP.NET AJAX Control Toolkit中的FilteredTextBox擴展器讓用戶只能在其中以一種指定模式輸入文本。這樣,若使用繼承的方式來實現這兩種擴充,我們的系統中則必須維護四種對象:TextBox、AutoCompleteTextBox、FilteredTextBox以及FilteredAutoCompleteTextBox。如果某一天我們還要給TextBox添加水印的功能(即ASP.NET AJAX Control Toolkit中的TextBoxWatermark擴展器所實現的功能),則需要維護的TextBox的種類則將增加為8種!長此以往,這種“類爆炸”的結果將讓系統非常難以擴展或維護。若采用應用了裝飾模式的擴展器控件的方式,則只要維護這幾個擴展器,并在需要時從中選擇并添加到某個TextBox上。 ?
寫作感想
結構化、有組織的論述問題 文章要符合讀者的閱讀習慣(重復好多遍了) 我似乎變得越來越能寫了,可是語言越來越蒼白 擁抱變化有點累 (還沒想好……) (PS:本文部分內容選自我的Atlas著作——《ASP.NET AJAX程序設計——第I卷:服務器端ASP.NET 2.0 AJAX Extensions與ASP.NET AJAX Control Toolkit》,將于明年一月出版,希望大家支持。)
總結
以上是生活随笔 為你收集整理的拥抱变化——从Atlas到ASP.NET AJAX(4):大大简化的了的Extender扩展器控件 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。