はじめに
Periodic Refresh(定期リフレッシュ)パターンを使用するAjax対応コンポーネントは、サーバを定期的にポーリングして変更がないかどうかを確認します。この記事では、AjaxNotifierという名前のAjax対応カスタムコントロールの開発を通じて、Periodic Refreshパターンを用いた独自のAjax対応コントロールの開発方法を説明します。
AjaxNotifierは、サーバを定期的にポーリングして、最新の通知がポストされていないかどうかを確認し、その通知を図1のようなポップアップダイアログに表示します。このポップアップダイアログには、通知の送信元と通知の内容が示されます。
![図1 図1](http://cz-cdn.shoeisha.jp/static/images/article/1518/image_001.gif)
この処理のワークフローを以下に示します。
- AjaxNotifierは、DOMとJavaScriptを使用して、ユーザーに示されている最新の通知IDを取得します。通知IDには、通知の発行順序を特定するのに必要な情報がすべて含まれています(例えば、通知の作成日を示すタイムスタンプなど)。
- AjaxNotifierは、ASP.NET 2.0クライアントコールバックメカニズムを使用して、サーバに対して非同期コールバックを行い、最新の通知に関する情報が含まれるXMLドキュメントをダウンロードします。また、これまでにユーザーに表示した最新の通知IDをサーバに渡して、サーバが次の通知をクライアントに送り返せるようにします。
- 次に、AjaxNotifierは、XML、DOM、およびJavaScriptを使用して、必要なデータをXMLドキュメントから動的に取得し、ポップアップダイアログに表示します。
AjaxNotifierコントロールは、WebControl基本クラスから派生しており、ICallbackEventHandlerインターフェースを実装します。このコントロールは、WebControlクラスの次のメソッドをオーバーライドします。
- OnPreRender
- AddAttributesToRender
- TrackViewState
- SaveViewState
- LoadViewState
WebControlからの派生
リスト1に、OnPreRender
メソッドの実装を示します。
protected override void OnPreRender(EventArgs e) { DetermineRenderClientScript(); if (renderClientScript) { string js = Page.ClientScript.GetCallbackEventReference( this, "GetNotificationId('"+ClientID+"')", "AjaxNotifierCallback", "'" + ClientID + "'", true); string js2 = "function DoCallback () {" + js + ";}"; Page.ClientScript.RegisterClientScriptResource (typeof(AjaxNotifier), "CustomComponents.AjaxNotifier.js"); Page.ClientScript.RegisterClientScriptBlock(typeof(AjaxNotifier), typeof(AjaxNotifier).FullName + "DoCallback", js2, true); Page.ClientScript.RegisterStartupScript(typeof(AjaxNotifier), typeof(AjaxNotifier).FullName + "WebDoCallback", js,true); } base.OnPreRender(e); }
OnPreRender
は、3つのスクリプトブロックを登録します。最初のスクリプトブロックは、「CustomComponents.AjaxNotifier.js」埋め込みリソースを参照します。
Page.ClientScript.RegisterClientScriptResource(typeof(AjaxNotifier),
"CustomComponents.AjaxNotifier.js");
埋め込みリソースについては、『Professional ASP.NET 2.0 Server Control and Component Development』(Shahram Khosravi 著、Wrox Pr Inc.、2006年8月)の第26章「Developing Ajax-Enabled Controls and Components:Client-Side Functionality」で詳しく説明しています。「AjaxNotifier.js」スクリプトファイルには、AjaxNotifierコントロールが使用するJavaScript関数が含まれています。この記事では、このJavaScript関数について詳しく説明します。
2番目のスクリプトブロックには、DoCallback
というJavaScript関数のコードが含まれています。この関数は、ページのClientScript
プロパティのGetCallbackEventReference
メソッドが返すJavaScriptコードを実行します。『Professional ASP.NET 2.0 Server Control and Component Development』の第27章「Developing Ajax-Enabled Controls and Components:Asynchronous Client Callback」で触れているように、このJavaScriptコードには、サーバへの非同期クライアントコールバックを行うJavaScript関数の呼び出しが含まれています。
string js = Page.ClientScript.GetCallbackEventReference( this, "GetNotificationId('"+ClientID+"')", "AjaxNotifierCallback", "'" + ClientID + "'", true); string js2 = "function DoCallback () {" + js + ";}";
3番目のスクリプトブロックには、サーバへの非同期クライアントコールバックを行うJavaScript関数の呼び出しが含まれます。OnPreRender
がRegisterStartupScript
メソッドを使ってこのスクリプトを登録し、ページ下部のスクリプトをレンダリングするようページに要求していることに注目してください。これは、ページのロード直後に最初の非同期呼び出しが行われることを意味します。この重要性については後で説明します。
Page.ClientScript.RegisterStartupScript(typeof(AjaxNotifier),
typeof(AjaxNotifier).FullName + "WebDoCallback", js,true);
リスト2に、AjaxNotifierコントロールのAddAttributesToRender
メソッドのコードを示します。
protected override void AddAttributesToRender(HtmlTextWriter writer) { base.AddAttributesToRender(writer); if (renderClientScript) { CssStyleCollection col; writer.AddAttribute("notificationId", "0"); if (dialogStyle != null) { col = dialogStyle.GetStyleAttributes(this); writer.AddAttribute("dialogStyle", col.Value); } if (headerStyle != null) { col = headerStyle.GetStyleAttributes(this); writer.AddAttribute("headerStyle", col.Value); } if (itemStyle != null) { col = itemStyle.GetStyleAttributes(this); writer.AddAttribute("itemStyle", col.Value); } if (alternatingItemStyle != null) { col = alternatingItemStyle.GetStyleAttributes(this); writer.AddAttribute("alternatingItemStyle", col.Value); } } }
AjaxNotifierがポップアップ表示するダイアログは、ダイアログのリサイズ時にクライアントサイドで行われるすべての処理(例えばレンダリング、移動、リサイズ、フォント調整など)を自ら担当します。従って、このポップアップダイアログはサーバーコントロールではありません。第27章では、このポップアップダイアログのようなクライアントサイドコンポーネントのCSSスタイル属性をAjax対応コントロール自身の最上位プロパティとして公開する方法を説明しています。
AjaxNotifierは、前述した第27章のAjaxDetailsDialog
が公開するのと同じ最上位プロパティを公開します。また、AjaxNotifierコントロールでは、TrackViewState
メソッド、SaveViewState
メソッド、およびLoadViewState
メソッドをオーバーライドすることで、これらの最上位プロパティの状態をページのポストバック間で管理しています。これについては、第27章で詳しく説明します。