カスタム AJAX クライアント コントロールの作成
更新 : 2007 年 11 月
この概要では、カスタムの ASP.NET AJAX クライアント コントロールを作成し、ページで使用する方法を示します。この概要では、次の操作の実行方法について説明します。
ECMAScript (JavaScript) でプロトタイプ デザイン パターンを使用して、コントロール クラスを定義する。
コントロールを、Sys.UI.Control 基本クラスから派生したクラスとして登録する。
Control 基本クラスを初期化し、このクラスのメソッドを呼び出す。
ページ作成者が関連付けて処理できるカスタム イベントを作成する。
クライアント コントロールをページ内で使用し、コントロールのイベントに関連付ける。
この概要では、マウス ポインタが上に置かれたときの動作を割り当てたボタンを作成する、完全なクライアント コントロールの例を示します。
ここでは、クライアント コントロールに焦点を絞って説明します。ASP.NET AJAX クライアント コンポーネント オブジェクトには、3 つの種類があります。
Sys.Component 基本クラスから派生する、UI として表示されない非ビジュアルのコンポーネント
Sys.UI.Behavior から派生する動作
Control から派生するコントロール
コンポーネント、動作、およびコントロールの相違点を次の表に示します。
クライアント コンポーネント オブジェクトの種類 |
概要 |
---|---|
コンポーネント |
|
動作 |
|
コントロール |
|
前提条件
このトピックで示されるクライアント コントロールの例を実行するための要件は、次のとおりです。
- AJAX 対応の ASP.NET Web サイト。同様のサイトが既に構成されている場合は、そのサイトをこの例で使用できます。仮想のディレクトリまたはサイトを作成する方法の詳細については、「方法 : IIS 5.0 および 6.0 内で仮想ディレクトリを作成および構成する」を参照してください。
カスタム ASP.NET AJAX クライアント コントロールの基本機能の作成
ASP.NET AJAX クライアント コントロールは、DOM 要素をクライアント オブジェクトとして表し、マークアップ表現を拡張するか、またはその要素に機能を追加します。たとえば、別の CSS スタイルを適用することで、クライアント コントロールでマウス イベントに反応するように HTML 要素を拡張できます。
クライアント コントロールは、複数のアプリケーションで再利用することを目的とした JavaScript コードをカプセル化します。カスタム コントロールは、Control 基本クラスから派生することで、次のような多数の組み込みクロス ブラウザ機能を自動的に継承します。
コントロールに関連付けられている DOM 要素のイベント ハンドラ、およびコントロール自体のイベント ハンドラを追加および削除する機能。
Sys.IDisposable インターフェイスを実装するコントロールを、破棄できるオブジェクトとして自動的に登録する機能。
プロパティが変更されたときに通知イベントを発生させる機能。
コントロールのプロパティ設定のバッチ処理を実行する機能。この機能により、プロパティの各 get アクセサおよび set アクセサですべてのロジックを処理するよりも、スクリプトのサイズが小さくなり、処理時間も短縮できます。
クライアント コントロールの実装
次の表に、Control から派生したカスタム クライアント コントロールを実装する手順をまとめます。次の表で、各手順の詳細を説明します。
ステップ |
概要 |
---|---|
プロトタイプ デザイン パターンを使用して、クライアント コントロール クラスを定義します。 |
|
コントロールの Control 基本インスタンスを初期化し、関連付けられている DOM 要素を引数として渡します。 |
|
プロパティ アクセサを公開し、必要に応じて Sys.Component.propertyChanged 通知イベントを発生させます。 |
|
Sys.UI.Control.initialize メソッドをオーバーライドして、プロパティとイベント リスナを初期化します。 |
コンポーネントまたは DOM 要素に初期化の必要なプロパティやイベント リスナがある場合は、コンポーネントのプロトタイプ内で initialize メソッドをオーバーライドします。オーバーライドしたメソッドで、以下の作業を行います。
|
Sys.UI.Control.dispose メソッドをオーバーライドしてリソースを解放します (DOM イベント ハンドラを削除するなど)。 |
コントロールを破棄する前にリソースを解放する場合は、コンポーネントのプロトタイプ内で dispose メソッドをオーバーライドします。オーバーライドしたメソッドで、以下の作業を行います。
|
プロトタイプ デザイン パターンを使用したコントロール クラスの定義
ASP.NET AJAX クライアント クラス (コントロール クラスを含む) は、JavaScript でプロトタイプ デザイン パターンを使用して定義されます。詳細については、「プロトタイプ モデルを使用したクライアント コンポーネント クラスの作成」を参照してください。
クライアント コントロール クラスは、Control 基本クラスから派生させる必要があります。ASP.NET AJAX クライアント クラスをクラスとしてクライアント アプリケーションに登録するには、Type.registerClass メソッドを使用します。詳細については、「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" runat="server">
<asp:ScriptManager runat="server" 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 メソッドを呼び出して、スクリプトの読み込みが完了したことをアプリケーションに通知する必要があります。ただし、アセンブリに埋め込まれたスクリプトでは、多くの場合、このメソッドを呼び出さないようにする必要があります。詳細については、「Sys.Application.notifyScriptLoaded メソッド」を参照してください。 |
ScriptManager コントロールを使用してスクリプト ファイルを登録する方法以外に、IScriptControl インターフェイスを実装するカスタム サーバー コントロールを使用して、クライアント コンポーネントを管理することもできます。カスタム サーバー コントロールでは、必要なコンポーネント スクリプトの登録や、コンポーネント プロパティの設定およびイベントの関連付けを行う宣言マークアップの公開を、自動的に実行できます。これにより、ページ作成者がカスタム コントロールを使用しやすくなります。詳細については、IScriptControl クラスの概要を参照してください。
カスタム コントロール インスタンスの作成
カスタム クライアント コントロールをインスタンス化するには、Sys.Component.create メソッドまたは $create ショートカットを Sys.Application.init イベントの処理時に呼び出します。次の表では、クライアント コントロールの作成時に $create メソッドに渡すパラメータを示します。
パラメータ |
説明 |
---|---|
type |
コンポーネントの種類。 |
properties |
コンポーネント ID の値およびオプションでプロパティの名前と値のペアの初期値を含んでいる JSON オブジェクト。 |
events |
イベント名およびイベントとハンドラを関連付けたペアを含んでいる、オプションの JSON オブジェクト。 |
references |
コンポーネントの名前と ID のペアとして渡される関連コンポーネントへの参照を含んでいる、オプションの JSON オブジェクト。 |
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 コントロールは、関連付けられている button HTML 要素の click、focus、および mouseover の各イベントを受け取ります。また、$create メソッドを通じて関連付けることができるイベントをコントロールに提供します。HoverButton コントロールを使用するページ作成者は、コントロールの hover イベントを関連付けることができます。
HoverButton コントロールのコードを作成するには
AJAX 対応の ASP.NET Web サイトのルート ディレクトリに、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" runat="server"> <style type="text/css"> button {border: solid 1px black} #HoverLabel {color: blue} </style> <title>Control Demo</title> </head> <body> <form id="form1" runat="server"> <div id="ResultDisplay"></div> <asp:ScriptManager runat="server" 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 には、必須のコントロール ID 値の後に、プロパティ名の初期値を指定するプロパティの名前と値のペアが格納された JSON オブジェクトを指定します。
引数 events には、イベント名とそのハンドラを組み合わせたオブジェクトを指定します。
ScriptManager コントロールでは、asp:ScriptReference ノードの path 属性で、Demo.HoverButton コントロール クラスを定義する HoverButton.js ファイルのパスが参照されています。
DOM 要素のイベント ハンドラおよびコンポーネントのイベント ハンドラの設定
ASP.NET の AJAX 機能には、コンポーネントおよび DOM 要素で標準的なイベント管理を可能にするクラスが含まれます。コントロールのイベントを管理するには、Sys.EventHandlerList クラスのメンバである addHandler や removeHandler などを使用します。詳細については、Sys.EventHandlerList クラスの概要を参照してください。
DOM 要素または window オブジェクト イベントのイベント ハンドラを管理するには、Sys.UI.DomEvent クラスの静的メソッド、addHandler、または removeHandler を使用します。詳細については、Sys.UI.DomEvent クラスの概要を参照してください。
DOM 要素のプロパティへのアクセス
Sys.UI.DomElement クラスには、クライアント コントロールおよびクライアント要素に対する CSS クラスの関連付けの追加、削除、および切り替えを行うためのメンバが含まれています。これらのメンバを使用して、DOM 要素のプロパティに標準的なアクセスを行うこともできます。詳細については、「Sys.UI.DomElement クラス」を参照してください。
参照
処理手順
概念
ASP.NET UpdatePanel コントロールとデータ バインド コントロールの使用