ASP.NET MVC Razor をやってみた。 IgniteUI 編 その1 igGridのロードオンデマンドについて(1/2)
ASP.NET MVC 周辺の記事を書きたいなと思います。ここしばらくは、私が運営している [喜帳面.net]でも使ってる、お気に入りの開発ツール「IgniteUI」の周辺について [喜帳面.net]での事例などを織り交ぜながら、メモを残しておきます。
IgniteUIでどんなことができるかは、以下のURLを参考にしてください。
http://jp.infragistics.com/products/aspnet-mvc
ヘルプやAPIドキュメントは以下のページの「jQuery/HTML5」を参照してください。
この記事記載時の最新のバージョンは2015 Volume 1 ですがこの記事は、2013 Volume 2 ベースでの情報です。
さて、「IgniteUI」といえばまず試してみたくなるのがGridですね。
igGridはあまりにも機能が多くて最初は戸惑ってしまいますよね。今回は「ロードオンデマンド」機能について思うところを記載します。
igGridを試してみようと各種サンプルやドキュメントを参照すると、View(cshtml)にGridのさまざまな定義を記述する事例を目にすると思います。で、そのサンプルを真似てコードを起こすと意外なほど簡単に高機能なGridが実装できます。「そうか、こんな感じでいいんだ了解!」っとGridの量産に入る前に、是非「ロードオンデマンド機能」を検討してみてください。Gridを沢山開発する予定がある場合「ロードオンデマンド機能」を使えば、汎用性の高いGridをより効率よく実装できる可能性があります。
ロードオンデマンド (igHierarchicalGrid) - Ignite UI™ ヘルプ
ロード オン デマンド サンプル - Hierarchical Grid コントロールの ロード オン デマンド - Ignite UI™
上記は、ヘルプとサンプルへのリンクで、igHierarchicalGrid(階層を持つGrid)の
説明のように感じる位置に配置されています。解説では親子の2階層でできているGridの子のデータの取得を、オンデマンドつまり親行の左端にある[+]アイコンをクリックして子の行を展開する時点で行う例が記載されています。ちなみに、ロードオンデマンド機能を使用しない階層型のGridの場合は、最初のデータ取得時に「親子の階層を持ったModelのデータ」を一括で受け取ります。
これだけ見ると、「ロードオンデマンド機能って階層型Gridの場合の、子階層のデータを親行の展開時に取得する機能」と思ってしまうかもしれませんが、それだけではありません。ロードオンデマンドは、階層を持たないGridでも有効です。私はこの機能の最大の特徴は、「Gridの定義を、View(.cshtml)ではなくController(.cs)やModel(.cs)に記述する」ことにあると思ってます。Controller(.cs)やModel(.cs)で記述することで、View(.cshtml)に記述する場合よりも、もっと柔軟なGrid定義が可能になります。
Gridの定義をデータベースに保存しておいて、Model(.cs)で読み取り、その情報に従ってView上のGridを表示する、そんなことも可能になりますよ。
手前味噌になりますが、拙作[喜帳面.net]では、「取引伝票の発行」という処理でロードオンデマンド機能を使用しています。この処理のGridで一般的な手法ではなく、ロードオンデマンド機能を採用するに至った背景などをちょっと説明させてください。
この処理では、伝票を発行するにあたって、発行対象とする伝票の一覧を階層型Gridに表示し、伝票に表示する備考等を伝票毎に登録することが可能になっています。
備考等は10項目以上あり、ログインユーザーが各項目の使用有無を事前に設定可能になっています。で、ユーザーが使用しないと設定した項目については、伝票一覧Grid上にも表示されないようにしたかった訳です。
以下の画像で出来上がりの雰囲気をつかんで下さい。
子階層行には明細行の内容を表示しています。横方向にスクロールしてGrid上の「備考等」の内容が確認できます。
各行には編集アイコンが配置されており、このアイコンのクリックで編集ダイアログが開き、「備考等」の項目が入力可能になります。
ダイアログを閉じると、編集内容がGridに格納されます。
発行対象の伝票のチェックボックスにチェックを入れて、「PDF作成」ボタンクリックすると、Grid内の伝票発行に必要な情報がAjaxでpostされた後サーバー側でPDFを作成しクライアントにダウンロードされます。
「備考等」の項目は、「伝票マスタの保守」で事前に使用有無の設定ができるようになっています。
見出し部が空白になっている項目は、使用しない項目として扱い、一覧のグリッド上および編集ダイアログ上にも表示されなくなります。
この処理の開発当初、私はロードオンデマンド機能を知らなかった為、使用しない設定項目をGridの描画完了時に「隠してしまう方法」をとっていました。
現在は、 ロードオンデマンド機能を利用して、使用しない設定項目については「定義しない方法」を採用しています。
「隠してしまう方法」ですが、javascriptで hideColumnしてました。
こんな感じです。
//伝票一覧 全データ レコードが描画された時、使用しない列(headerTextがnullか"")は隠す
$(document).on("iggriddatarendered", "#gridList", function (evt, ui) {
var gridName = "#"+this.id;
var columnslength = ui.owner.options.columns.length;
for (i = 1; i < columnslength; i = i + 1) { //全列ループ
if (ui.owner.options.columns[i].hidden == false) {
var headerText = ui.owner.options.columns[i].headerText;//見出し取得
if((headerText == null)||(headerText == "")){
var key = ui.owner.options.columns[i].key; //key取得
$(gridName).igGrid("hideColumn", key); //列を隠す
}
}
}
});
この方法だと、グリッドの描画中に表示されるぐるぐる画像が途中でぴたっと停止し、しばらく(ほんの数秒ですが)経過した後でGrid操作が可能になります。列を隠す処理は思ってた以上に負荷がかかっているようです。親階層の行数や子階層の行数に影響を受けるのか否かは確認できていませんが、隠す列数の増加は影響していそうです。
ほんの数秒のことなのですがちょっと気になったので、資料をいろいろ見ていて、ロードオンデマンド機能に行き当たりました。前述したように、私はこの機能って単に
子データの取得を親行の展開時に行うだけと思い込んでいました。ちゃんと読んでみると、そんなんじゃなくて、Gridの定義を.cshtlmではなく、ControllerやModel classで定義できることが解ったわけです。そう、ロードオンデマンド機能を使えば、サーバー側で、列を隠すとか、そもそも列自体無いものにしてしまう、また、列の順や見出しのテキストなど、おおよそcshtmlに記述していた内容を制御できてしまいます。
見出しのテキスト1つとっても、今までは@ViewBagを使ったり、javascriptで書き換えるとか、記述が複数個所に存在し、ちょっと面倒でした。
そこで、思い切ってロードオンデマンド機能にチェレンジしてみました。その内容は次回にアップします。
今回は以上です。