連載:Microsoft AJAX Library&JavaScriptプログラミング

第2回 PageRequestManagerクラスでUpdatePanelコントロールを極める!

山田 祥寛(http://www.wings.msn.to/
2007/11/16

■部分更新時にサーバサイドから追加情報を取得するには?

 UpdatePanelコントロールは、パネル配下のコンテンツを更新するばかりではない。非同期ポストバックに際してサーバサイドから取得した追加的な情報でもって、パネル外のコンテンツを更新することも可能だ。

 もちろん、このような処理を実装するために、最初からブリッジ機能を利用するという方法もあるかもしれないが、主要なコンテンツの更新はUpdatePanelコントロールに委ねつつ、関連する付随データの受け渡しを行いたいという場合には、UpdatePanelコントロール+PageRequestManagerクラスを利用するのが便利である。

 ここでは、その具体的な例として、別稿「DBプログラミング 7つのヒント− 同時実行制御からASP.NET AJAXまで −」の「Hint 5」でも紹介した「GridViewAjax.aspx」を取り上げる。

 以下のサンプルは、グリッド表の部分更新時に、更新されたレコードのキー情報をページ上部に表示するものだ。


グリッド表で更新されたレコードのキー情報をページ上部に表示

 用意するのは、以下のようなWebフォームとイベント・ハンドラだ。なお、以下では、別稿の「Hint 5」からの変更分にフォーカスして手順を紹介する。GridViewコントロールそのものの設定などは、元の記事の方を参照いただきたい。


Webフォーム(GridViewAjax.aspx)のフォーム・レイアウト(変更分のみ)
追加しているコントロールは以下の表のとおり。

コントロール(ID) プロパティ 設定値
Label(lblStatus) Text △(ブランク)
コントロールのプロパティ設定

Protected Sub grid_RowUpdated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdatedEventArgs)
  manager.RegisterDataItem(Me.lblStatus, e.Keys("isbn"), False)
End Sub
protected void grid_RowUpdated(Object sender, System.Web.UI.WebControls.GridViewUpdatedEventArgs e) {
  manager.RegisterDataItem(this.lblStatus, (String)e.Keys["isbn"], false);
}
リスト14 更新されたレコードの主キーを拡張情報として登録するイベント・ハンドラ(GridViewAjax.aspx。上:VB、下:C#)

 ページ上の任意の要素に対して追加情報を登録するのは、ScriptManagerコントロール(manager)のRegisterDataItemメソッドの役割だ。RegisterDataItemメソッドの構文は以下のとおり。

RegisterDataItem(
  追加情報を関連付けるコントロール,
  追加情報,
  [JSON形式でエンコード済みか]
)
RegisterDataItemメソッドの構文

 ここでは、Labelコントロール「lblStatus」に対して、更新に使用されたキー情報を関連付けているというわけだ。更新キーは、GridViewUpdatedEventArgsオブジェクトのKeyプロパティにより取得できる。

 ちなみに、関連付けるコントロールは、厳密には必ずしもLabelコントロール(表示先)である必要はない。ここで指定されたコントロールは、あくまでクライアントサイドでアクセスする際のキーとなる情報にすぎないので、(例えば)UpdatePanelコントロールやGridViewコントロールに関連付けても間違いではない。ただし、コードの可読性を考えるならば、当然、最も関連の深いコントロールとひも付けておくのが無難だろう。

[参考]追加情報に構造データを引き渡すには?

 RegisterDataItemメソッドの第2引数には、オブジェクトや配列のような構造データを引き渡すことも可能だ。ただし、その場合には、以下のようなシリアライズ処理を行っておく必要がある。

Dim j As New JavaScriptSerializer()
manager.RegisterDataItem(Me.lblStatus, j.Serialize(obj), True)
JavaScriptSerializer j = new JavaScriptSerializer();
manager.RegisterDataItem(this.lblStatus, j.Serialize(obj), true);
リスト15 構造データをシリアライズするためのコード(上:VB、下:C#)

 構造データのシリアライズを行うのは、JavaScriptSerializerクラス(System.Web.Script.Serialization名前空間)の役割だ。serializeメソッドによって、指定された任意のオブジェクトをJSON(JavaScript Object Notation)形式*3にシリアライズすることができる。

 このようにシリアライズされた構造データをクライアントサイドで処理する方法については、別稿「.NET TIPS:[ASP.NET AJAX]Webサービス・ブリッジ機能により構造化データを受け渡しするには?(基本編)」などでも紹介しているので、併せて参照いただきたい。

*3 JSONとはその名のとおり、JavaScriptで扱えるオブジェクト表現をほとんどそのままに利用したデータ・フォーマットのこと。XML形式に比べてデータの冗長度が低く、JavaScriptからも(データの変換などを行うことなく)直感的に利用できることから、昨今ではAJAXアプリケーションでXMLよりも多く利用されているフォーマットだ。

 さて、サーバ側での追加情報の登録ができたら、後はこれをクライアント側で取得し、ページ上に反映するだけだ。追加情報は、pageLoading、pageLoaded、endRequestいずれかのイベント・ハンドラを介して取得することができる。

<script type="text/javascript">

<!--
function pageLoad() {

  var mng = Sys.WebForms.PageRequestManager.getInstance();

  // ページへの更新反映後に呼び出されるイベント・ハンドラを定義
  mng.add_pageLoaded(
    function(sender, args) {

      // サーバ側で登録した追加情報を取得
      var item = args.get_dataItems()['lblStatus'];

      // 追加情報が空でない場合には、ラベル上にメッセージを反映
      if (item == null) {
        $get('lblStatus').innerHTML = '';
      } else {
        $get('lblStatus').innerHTML
                      = args.get_dataItems()['lblStatus']
                        + 'が更新されました。';
      }
    }
  );
}
//-->
</script>
リスト16 追加情報を取得し、ラベルに反映するためのJavaScriptのコード(GridViewAjax.aspx)

 サーバ側で登録された例外情報を取得するには、Sys.EventArgs派生クラスのdataItemsプロパティを参照すればよい。dataItemsプロパティはコントロール名をキーとした連想配列になっているので、

args.get_dataItems()['コントロール名']

のようにアクセスできる。コントロール名は、先ほどサーバ側のRegisterDataItemメソッドで指定したコントロールに対応している。

 以上、今回はPageRequestManagerクラスを利用することで、UpdatePanelコントロールによる非同期ポストバックの機能を拡張する方法について紹介した。

 UpdatePanelコントロールは、なるほど便利なコントロールであるが、あくまで定型的な部分更新の機能を提供するものだ。実際のアプリケーションを構築するうえでは、なかなか「かゆいところ」に手が届かない感も強いかもしれない(また、結果、ブリッジ機能に流れていってしまったという方も少なくないかもしれない)。

 しかし、PageRequestManagerクラスと連携することで、部分更新の機能はUpdatePanelコントロールに委ねつつ、付随する細かな制御だけをJavaScriptで行えることが分かったのではないだろうか。本稿で紹介した内容は、PageRequestManagerクラスでできることの一部にすぎないが、引き続き具体的な実用例については.NET TIPSでも紹介していく予定だ。ご期待いただきたい。

 次回は、ASP.NET AJAX+ASP.NET AJAX Control Toolkitを利用して、AJAX対応コントロールを自作する方法について紹介する予定である。End of Article


 INDEX
  Microsoft AJAX Library&JavaScriptプログラミング
  第2回 PageRequestManagerクラスでUpdatePanelコントロールを極める!
    1.UpdatePanelコントロールを拡張するPageRequestManagerクラスの基本
    2.ボタンの2重クリックを防止するには?/実行中の非同期ポストバックをキャンセルするには?
    3.非同期ポストバックの優先順位を制御するには?
    4.非同期ポストバックの完了を通知するには?/非同期ポストバック時に発生した例外を処理するには?
  5.部分更新時にサーバサイドから追加情報を取得するには?
 
インデックス・ページヘ  「Microsoft AJAX Library&JavaScriptプログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間