ASP.NET MVC Razor をやってみた。 IgniteUI 編 その4 igGridのGridUpdating機能について
ASP.NET MVC 周辺の記事を書きたいなと思います。ここしばらくは、私が運営している [喜帳面.net]で使ってる [IgniteUI]の周辺について [喜帳面.net]での事例などを織り交ぜながら、メモを残しています。
対象の環境は、ASP.NET MVC4 Razor C# でIgniteUIは2013 Volume 2 です。ちょっと古いけどあしからず。
IGNITEUIのヘルプ類はこちらの [ページ] のjQuery/HTML5部分を参照ください。
今回は、igGridの更新機能(igGridUpdating )についてメモしておきます。
1.トランザクションを利用したバッチ更新処理について
igGridの更新機能を使用するとgridのデータの追加・更新・削除を行うことができます。
gridのデータ操作内容はクライアントのトランザクションに格納されます。トランザクションを「rollback」することで操作の取り消しも可能です。
クライアントでigGridのsaveChangesメソッドを呼び出すと、igGridのUpdateUrlで指定したURLにトランザクションがpostされます。
サーバー側では、postされたデータを、GridModel.LoadTransactions(string postdata) を使用して逆シリアル化しトランザクションをリスト化、次にトランザクションの行毎のタイプ{"newrow","row","deleterow"など}を判定してデータベースへの更新処理などを行うことができます。
以上のことはこちらの [サンプル Grid基本編集] に詳しく記載されています。
※トランザクションを利用するには、igGridのオプションAutoCommitがfalseになっている必要があります。デフォルトはfalseになっています。
2.行内編集とダイアログ編集
下記画像は、上記のサンプルをもとに見よう見まねで更新処理機能を実装した [喜帳面.net]での事例です。管理者用の処理なので、メニューには登録していません。
grid表示時はこんな風に表示されています。
UpdatingのオプションにEditModeがあり、(GridEditMode.Cell, .None,.Row,.RowEditTemplate)から選択可能です。
.EditMode(GridEditMode.Row)と指定すると行内でのデータ編集となります。
「新規行の追加」をクリックした場合は、「新規行の追加」と記載されている行での編集処理となります。
.EditMode(GridEditMode.RowEditTemplate)を指定すると、ダイアログでのデータ編集となります。「新規行の追加」をクリックした場合もダイアログで追加レコードを入力します。
行の削除は、グリッド右端に表示される「×」アイコンをクリックします。
1行編集(追加や変更)が完了すると、グリッド上に変更後のデータが斜体で表示されます。また、削除データは「取り消し線」が引かれます。
これらのレコードはトランザクションが保留中の状態になっています。
サンプルでは、「元に戻す」ボタンをクリックすることで、保留中のトランザクションを"rollback"し編集操作を取り消しできるようになっています。
また、"rollback"したトランザクションについては「やり直す」ボタンをクリックすることで、ロールバックしたトランザクション再反映することができるようになっています。詳細は [サンプル Grid基本編集] を参照ください。
3.igGridの"commit"メソッド
igGridの"commit"メソッドを実行することで保留中のトランザクションをコミットできます。コミットされると画面上では、斜体から通常のフォント表示になります。
このトランザクションのコミットはあくまでもブラウザーに保持されているトランザクションがコミットされ「ロールバック」できない状態になったということになります。この状態からgridのデータを元にもどすにはgridのソースデータを再度取得し直す必要があります。
尚、igGridのsaveChangesメソッドでサーバーへpostした場合、トランザクションが保留中か否かに係らず(保留中のトランザクションも)送信されます。
4.igGridUpdatingの”datadirty”イベント
ページの移動、ソート、フィルター操作を行う場合は、事前に保留中のトランザクションをコミットしておきます。保留中のトランザクションが存在すると、「JavaScript 実行時エラー: グリッドに保留中のトランザクションがあります。データのレンダリングに影響する場合があります。(以降割愛)」の例外が発生します。datadirtyイベントを使用して回避します。
//ページ移動、ソート、フィルタの実施時はグリッドに保留中のトランザクションをコミットしてfalse を返します $(document).on("iggridupdatingdatadirty", "#grid1", function (event, ui) { $("#grid1").igGrid("commit"); //saving local changes to the datasource when sorting return false; });
5.EditorTypeでコンボを使用する場合
Loaderを使用する場合、Resourcesに"igCombo"の明示が必要です。
@(Html.Infragistics().Loader() .ScriptPath(Url.Content("~/Scripts/IG/js/")) .CssPath(Url.Content("~/Content/IG/css/")) .Resources("igCombo") //EditorTypeでComboを使う場合明示が必要 .Theme("metro") .Render() )
options.DataSourceUrlの使用は?? 未解決です。
今回私の事例では、EditorTypeにColumnEditorType.Comboを指定した列があります。まずデータの取得について、ComboEditorOptionsでDataSourceUrlを指定してみたのですが、ちょっとうまくない現象が発生しました。
こんなかんじの記述です。
9行目:options.DataSourceUrl(Url.Action("GetLanguageNameIDList"));
これでコンボ用のデータを取得しようとしています。この方法でコンボのリストは表示できるのですが、レコードの内容を変更しようとコンボを開いた時点で列の値が空白になってしまいます。編集モードが行の場合、一度開くと2レコード目以降では問題なく動作します。編集モードがRowEditTemplate場合は2レコード目以降の編集でもダイアログ内の当該コンボは空白で表示されてしまいます。
憶測ですが、コンボのレコードの取得は、レコードの編集を開始した後に実行され、編集の開始時点では、リストは空状態になっており、リストに存在しない値をセットして値がnullに置き換えられているような感じがします。
DataSourceUrlを使用した対策がどうにも見つけられないので、取り急ぎ「DataSource」とViewBagを使用した [サンプル Grid基本編集]でやってる手法で対応しました。それは、
コントローラーで,iggridを含むViewをクライアントに返す際に、コンボ用のデータリストをViewBagにセットしておく。
そして、ComboEditorOptionsのデータの取得はDataSourceでそのViewBagを指定します。
18行目のDataSourceUrlをコメントアウトし、19行目でDataSource指定しています。
今回は以上です。