建立自訂的 AJAX 用戶端控制項
更新:2007 年 11 月
本概觀說明如何建立自訂 ASP.NET AJAX 用戶端控制項以及如何在網頁中使用。在本概觀中,您將了解如何進行下列作業:
在 ECMAScript (JavaScript) 中使用原型設計模式定義控制項類別。
將控制項註冊為衍生自 Sys.UI.Control 基底類別的類別。
初始化 Control 基底類別和叫用其方法。
建立網頁開發人員可繫結和處理的自訂事件。
在網頁中使用用戶端控制項,並繫結至控制項的事件。
這個概觀提供完整用戶端控制項的範例,這個控制項會建立具有停留行為的按鈕。
這個概觀著重在用戶端控制項。ASP.NET AJAX 用戶端元件物件有三種類型:
衍生自 Sys.Component 基底類別且沒有 UI 表示的隱藏式元件。
衍生自 Sys.UI.Behavior 的行為。
衍生自 Control 的控制項。
下表摘要說明元件、行為與控制項之間的差異。
用戶端元件物件型別 |
摘要 |
---|---|
元件 |
|
行為 |
|
控制項 |
|
必要條件
若要執行此主題提供的用戶端控制項範例,您需要:
- 具備 AJAX 能力的 ASP.NET 網站。如果已經設定這類網站,您可以使用該網站來執行此範例。如需如何建立虛擬目錄或網站的詳細資訊,請參閱 HOW TO:在 IIS 5.0 和 6.0 中建立和設定虛擬目錄。
建立自訂 ASP.NET AJAX 用戶端控制項的基本功能
ASP.NET AJAX 用戶端控制項以用戶端物件表示 DOM 項目,並為該項目延伸標記表示或提供其他功能。例如,用戶端控制項可能延伸 HTML 項目,藉由套用不同的 CSS 樣式來反應滑鼠事件。
用戶端控制項封裝可跨應用程式重複使用的 JavaScript 程式碼。從 Control 基底類別衍生您的自訂控制項,控制項就會自動繼承許多內建的跨瀏覽器功能,包括:
能夠為控制項相關的 DOM 項目加入和移除事件處理常式,以及加入和移除控制項本身的事件處理常式。
自動將控制項註冊為可處置物件,這個物件實作 Sys.IDisposable 介面。
當屬性變更時引發通知事件的功能。
能夠執行控制項屬性設定的批次處理。對於指令碼大小與處理時間,這種方式比使用個別屬性 get 與 set 存取子 (Accessor) 處理所有邏輯來得有效率。
實作用戶端控制項
下表摘要說明實作自訂用戶端控制項的步驟,該控制項衍生自 Control。表格後面說明每個步驟的詳細資訊。
步驟 |
摘要 |
---|---|
使用原型設計模式定義用戶端控制項類別。 |
|
初始化控制項的基底 Control 執行個體,並傳遞關聯的 DOM 項目做為引數。 |
|
公開 (Expose) 任何屬性存取子,並選擇性地引發 Sys.Component.propertyChanged 通知事件。 |
|
覆寫 Sys.UI.Control.initialize 方法以初始化任何屬性與事件接聽程式 (Event Listener)。 |
如果元件或 DOM 項目需要初始化任何屬性或事件接聽程式,請覆寫元件原型中的 initialize 方法。在覆寫方法中,請執行下列動作:
|
覆寫 Sys.UI.Control.dispose 方法以釋放資源,例如移除 DOM 事件處理常式。 |
如果在處置 (Dispose) 控制項之前需要釋放任何資源,請覆寫元件原型中的 dispose 方法。在覆寫方法中,請執行下列動作:
|
使用原型設計模式定義控制項類別
在 JavaScript 中使用原型設計模式定義包含控制項類別的 ASP.NET AJAX 用戶端類別。如需詳細資訊,請參閱 使用原型模型建立用戶端元件類別。
用戶端控制項類別必須衍生自 Control 基底類別。使用 Type.registerClass 方法,將 ASP.NET AJAX 用戶端類別註冊為用戶端應用程式的類別。如需詳細資訊,請參閱 Type.registerClass 方法。
初始化基底類別
在控制項的建構函式中初始化基底 Control 物件。在控制項的建構函式中,叫用繼承的 initializeBase 方法,並將建構函式引數中接收的 DOM 項目傳遞至基底類別。通常是在建構函式中執行其他任何程式碼之前叫用 initializeBase 方法。初始化 Control 基底類別後,其方法可供控制項使用,且會自動使用 Sys.Application 執行個體將控制項註冊為可處置物件。如需詳細資訊,請參閱 Sys.IDisposable 介面。
下列範例顯示衍生自 Control 之控制項的建構函式。元件的建構函式會呼叫繼承的 initializeBase 方法。
Samples.SimpleControl = function(element)
{
Samples.SimpleControl.initializeBase(this, [element]);
}
定義屬性和引發屬性變更通知
您可以在用戶端控制項的類別中,定義可供網頁開發人員取得和設定的屬性。您也可以為元件的屬性引發 propertyChanged 通知事件。使用您元件的網頁開發人員就可以繫結至這些事件。衍生自 Component、Behavior 或 Control 基底類別的 ASP.NET AJAX 元件會繼承 Sys.Component.raisePropertyChanged 方法,您可以呼叫這個方法來引發 propertyChanged 事件。如需詳細資訊,請參閱定義自訂元件屬性和引發 PropertyChanged 事件。
初始化屬性與事件接聽程式
如果自訂控制項必須初始化所有屬性或事件接聽程式,請覆寫元件原型中的 initialize 方法。衍生自 Control 基底類別的用戶端控制項,通常會將任何處理常式繫結至其 DOM 項目事件,並將 DOM 項目屬性設定為初始值。在最後的步驟中,您必須呼叫基底 initialize 方法,讓元件的基底類別完成初始設定。
釋放資源
如果自訂控制項必須在處置控制項之前釋放資源,請覆寫 dispose 方法,並在覆寫方法中釋放資源。這樣可確保在處置控制項之前會立即釋放資源。釋放的資源包括用來繫結至 DOM 事件的處理常式。為了確保可從記憶體中移除物件,請驗證已移除 DOM 項目與元件物件之間可能的任何循環參考。如需詳細資訊,請參閱釋放元件資源。
在網頁中使用控制項
若要在 ASP.NET Web 網頁中使用自訂用戶端控制項,您必須執行下列動作:
在 Web 網頁中註冊用戶端控制項的指令碼程式庫。
建立用戶端控制項執行個體。
以下章節提供關於這些步驟的詳細資訊。
在 Web 網頁中註冊控制項的指令碼程式庫
您可以在網頁上使用 ScriptManager 控制項,以宣告方式或程式設計方式註冊用戶端控制項所需的指令碼。
下列範例說明 ScriptManager 控制項的宣告式標記,這個控制項可註冊控制項指令碼。
<form id="form1" >
<asp:ScriptManager ID="ScriptManager01">
<scripts>
<asp:ScriptReference path="HoverButton.js" />
</scripts>
</asp:ScriptManager>
</form>
asp:ScriptManager 項目在 scripts 節點內包含 asp:ScriptReference 項目。asp:ScriptReference 項目的 path 屬性參考 HoverButton.js 檔案的路徑,這個檔案定義控制項類別。如需詳細資訊,請參閱動態指派指令碼參考與 ScriptManager 類別概觀。
注意事項: |
---|
所有以 ScriptManager 控制項註冊的獨立指令碼檔案都必須呼叫 notifyScriptLoaded 方法,通知應用程式指令碼已完成載入。在大部分情況下,內嵌在組件 (Assembly) 中的指令碼不應該呼叫此方法。如需詳細資訊,請參閱Sys.Application.notifyScriptLoaded 方法。 |
除了使用 ScriptManager 控制項註冊指令碼檔案之外,您也可以使用實作 IScriptControl 介面的自訂伺服器控制項來管理用戶端元件。自訂伺服器控制項可以自動註冊所需的元件指令碼,並公開宣告式標記以設定元件屬性與事件繫結。這樣可讓網頁開發人員更容易使用您的自訂控制項。如需詳細資訊,請參閱 IScriptControl 類別概觀。
建立自訂控制項執行個體
您可以在 Sys.Application.init 事件期間透過呼叫 Sys.Component.create 方法或 $create 捷徑來產生自訂用戶端控制項。下表說明您建立用戶端控制項時傳遞至 $create 方法的參數。
參數 |
描述 |
---|---|
type |
元件類型。 |
properties |
JSON 物件,包含元件 ID 值和任何選擇性初始屬性名稱/值組。 |
events |
選擇性 JSON 物件,包含事件名稱和事件/處理常式繫結組。 |
references |
選擇性 JSON 物件,包含關聯元件的參考,當做元件名稱/ID 組傳遞。 |
element |
要與控制項產生關聯的 DOM 項目。 |
下列範例顯示如何呼叫 $create 方法來產生控制項執行個體。
$create(Demo.HoverButton, {text: 'A HoverButton Control',element: {style: {fontWeight: "bold", borderWidth: "2px"}}}, {click: start, hover: doSomethingOnHover, unhover: doSomethingOnUnHover},null, $get('Button1'));
如需詳細資訊,請參閱 Sys.Component.create 方法和Sys.Component $create 方法。
建立自訂 HoverButton 控制項
在本章節中,您將延伸 Control 基底類別建立簡單的自訂用戶端控制項,名為 HoverButton,然後在網頁中使用這個控制項。HoverButton 控制項會攔截相關聯 HTML button 項目的 click、focus 和 mouseover 事件。也提供可透過 $create 方法繫結的事件給控制項。使用 HoverButton 控制項的網頁開發人員可以繫結至控制項的 hover 事件。
建立 HoverButton 控制項的程式碼
在具備 AJAX 能力的 ASP.NET 網站的根目錄中,建立名為 HoverButton.js 的檔案。
將下列程式碼加入至該檔案中:
Type.registerNamespace("Demo"); // Constructor Demo.HoverButton = function(element) { Demo.HoverButton.initializeBase(this, [element]); this._clickDelegate = null; this._hoverDelegate = null; this._unhoverDelegate = null; } Demo.HoverButton.prototype = { // text property accessors. get_text: function() { return this.get_element().innerHTML; }, set_text: function(value) { this.get_element().innerHTML = value; }, // Bind and unbind to click event. add_click: function(handler) { this.get_events().addHandler('click', handler); }, remove_click: function(handler) { this.get_events().removeHandler('click', handler); }, // Bind and unbind to hover event. add_hover: function(handler) { this.get_events().addHandler('hover', handler); }, remove_hover: function(handler) { this.get_events().removeHandler('hover', handler); }, // Bind and unbind to unhover event. add_unhover: function(handler) { this.get_events().addHandler('unhover', handler); }, remove_unhover: function(handler) { this.get_events().removeHandler('unhover', handler); }, // Release resources before control is disposed. dispose: function() { var element = this.get_element(); if (this._clickDelegate) { Sys.UI.DomEvent.removeHandler(element, 'click', this._clickDelegate); delete this._clickDelegate; } if (this._hoverDelegate) { Sys.UI.DomEvent.removeHandler(element, 'focus', this._hoverDelegate); Sys.UI.DomEvent.removeHandler(element, 'mouseover', this._hoverDelegate); delete this._hoverDelegate; } if (this._unhoverDelegate) { Sys.UI.DomEvent.removeHandler(element, 'blur', this._unhoverDelegate); Sys.UI.DomEvent.removeHandler(element, 'mouseout', this._unhoverDelegate); delete this._unhoverDelegate; } Demo.HoverButton.callBaseMethod(this, 'dispose'); }, initialize: function() { var element = this.get_element(); if (!element.tabIndex) element.tabIndex = 0; if (this._clickDelegate === null) { this._clickDelegate = Function.createDelegate(this, this._clickHandler); } Sys.UI.DomEvent.addHandler(element, 'click', this._clickDelegate); if (this._hoverDelegate === null) { this._hoverDelegate = Function.createDelegate(this, this._hoverHandler); } Sys.UI.DomEvent.addHandler(element, 'mouseover', this._hoverDelegate); Sys.UI.DomEvent.addHandler(element, 'focus', this._hoverDelegate); if (this._unhoverDelegate === null) { this._unhoverDelegate = Function.createDelegate(this, this._unhoverHandler); } Sys.UI.DomEvent.addHandler(element, 'mouseout', this._unhoverDelegate); Sys.UI.DomEvent.addHandler(element, 'blur', this._unhoverDelegate); Demo.HoverButton.callBaseMethod(this, 'initialize'); }, _clickHandler: function(event) { var h = this.get_events().getHandler('click'); if (h) h(this, Sys.EventArgs.Empty); }, _hoverHandler: function(event) { var h = this.get_events().getHandler('hover'); if (h) h(this, Sys.EventArgs.Empty); }, _unhoverHandler: function(event) { var h = this.get_events().getHandler('unhover'); if (h) h(this, Sys.EventArgs.Empty); } } Demo.HoverButton.registerClass('Demo.HoverButton', Sys.UI.Control); // Since this script is not loaded by System.Web.Handlers.ScriptResourceHandler // invoke Sys.Application.notifyScriptLoaded to notify ScriptManager // that this is the end of the script. if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
程式碼討論
程式碼會透過呼叫 Type.registerNamespace 方法來註冊 Demo 命名空間。建構函式會叫用繼承的 initializeBase 方法,使 Control 基底類別方法可供使用。接著,初始化的基底類別會將 Demo.HoverButton 執行個體註冊為用戶端應用程式的可處置物件。
在原型中,程式碼會宣告公用事件 click、hover 和 unhover。網頁開發人員可以加入和移除接聽這些事件的處理常式。接著,這些方法會透過控制項的事件處理常式集合,加入或移除指定的處理常式。您可以透過控制項的 Sys.EventHandlerList 物件,在您的控制項類別中加入和移除處理常式。EventHandlerList 物件會經由繼承的 Sys.Component.events 屬性,取得控制項的事件處理常式集合。在這個範例中,程式碼會叫用傳回的 EventHandlerList 物件的 Sys.EventHandlerList.addHandler 和 Sys.EventHandlerList.removeHandler 方法,以加入或移除處理常式。
HoverButton 類別覆寫基底 dispose 方法,在處置控制項之前,安全地處置任何控制項資源 (例如 DOM 事件的處理常式)。最後,程式碼會呼叫基底 dispose 方法,讓應用程式釋放控制項。
在 Web 網頁中使用 HoverButton 控制項
在本章節中,您將學習如何在 Web 網頁中使用用戶端指令碼建立控制項執行個體。
建立網頁來使用 HoverButton 控制項
在您放置 HoverButton.js 檔案的應用程式根目錄中,建立名為 DemoHoverButton.aspx 的檔案。
將下列標記和程式碼加入至這個檔案:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" > <style type="text/css"> button {border: solid 1px black} #HoverLabel {color: blue} </style> <title>Control Demo</title> </head> <body> <form id="form1" > <div id="ResultDisplay"></div> <asp:ScriptManager ID="ScriptManager01"> <scripts> <asp:ScriptReference Path="HoverButton.js" /> </scripts> </asp:ScriptManager> <script type="text/javascript"> var app = Sys.Application; app.add_init(applicationInitHandler); function applicationInitHandler(sender, args) { $create(Demo.HoverButton, {text: 'A HoverButton Control',element: {style: {fontWeight: "bold", borderWidth: "2px"}}}, {click: start, hover: doSomethingOnHover, unhover: doSomethingOnUnHover},null, $get('Button1')); } function doSomethingOnHover(sender, args) { hoverMessage = "The mouse is over the button." $get('HoverLabel').innerHTML = hoverMessage; } function doSomethingOnUnHover(sender, args) { $get('HoverLabel').innerHTML = ""; } function start(sender, args) { alert("The start function handled the HoverButton click event."); } </script> <button type="button" id="Button1"></button> <div id="HoverLabel"></div> </form> </body> </html>
程式碼討論
DemoHoverButton.aspx 檔案是裝載自訂控制項的 ASP.NET Web 網頁。在這個網頁中,script 項目定義繫結至自訂控制項的函式。在 Sys.Application.init 事件處理常式中,用戶端指令碼會呼叫 $create 方法來產生 HoverButton 控制項。程式碼會將下列引數傳遞至 $create 方法:
type 引數包含您稍早建立的 Demo.HoverButton 類別。
properties 引數包含 JSON 物件,這個物件包含必要的控制項 ID 值,後面接著指定屬性名稱和初始值的屬性名稱值組。
events 引數包含一個物件,這個物件包含事件名稱及其處理常式。
在 ScriptManager 控制項中,asp:ScriptReference 節點的 path 屬性會參考 HoverButton.js 檔案的路徑,這個檔案定義 Demo.HoverButton 控制項類別。
設定 DOM 項目事件處理常式和元件事件處理常式
ASP.NET 中的 AJAX 功能包含類別,這些類別為元件和 DOM 項目提供標準化事件管理。您可以使用 Sys.EventHandlerList 類別的成員,例如 addHandler 和 removeHandler,以管理控制項的事件。如需詳細資訊,請參閱 Sys.EventHandlerList 類別概觀。
您可以使用 Sys.UI.DomEvent 類別的靜態方法 (addHandler 或 removeHandler),管理 DOM 項目或 window 物件事件的事件處理常式。如需詳細資訊,請參閱 Sys.UI.DomEvent 類別概觀。
存取 DOM 項目屬性
Sys.UI.DomElement 類別包含的成員,可讓您為用戶端控制項和項目加入、移除和切換 CSS 類別關聯。這些成員也提供 DOM 項目屬性的標準化存取。如需詳細資訊,請參閱 Sys.UI.DomElement 類別。
請參閱
工作
概念
搭配資料繫結控制項使用 ASP.NET UpdatePanel 控制項