CodeZineでjsRenderというものを知りました。
これは、面白そうということでぐぐってたら公式ページとともにMSDNマガジンの記事が…!?華麗にスルーしてたけど、公式とあわせて読むととりあえず大体OKっぽい。
LightSwitchはjQueryとjQuery mobileが使えたりするので、jQuery mobileのテーブルの出し方はこちらを参考にしました。
最近の個人的なJavaScriptの遊び場
こういうJavaScriptで遊ぶ時は最近LightSwitchのHTMLClientを使ってます。お手軽に基本的な画面は作れてJavaScriptで色々いじくるための骨組みができるのでとってもいい感じです。
jsRenderの取り込み
jsRenderの公式からjsviews.min.jsをDLしてきてLightSwitchのFileViewにしてScriptsフォルダに置きます。ついでに、LightSwitchのランタイム自体もNuGetで更新してテーマもダークにしてみました。*2
default.htmのcssのファイル名をバージョンアップしたcssのバージョン番号とあうように変更します。
<linkrel="stylesheet"type="text/css"href="Content/dark-theme-1.0.1.css" /><linkrel="stylesheet"type="text/css"href="Content/msls-dark-1.0.1.css" /><linkrel="stylesheet"type="text/css"href="Content/jquery.mobile.structure-1.3.1.min.css" /><linkrel="stylesheet"type="text/css"href="Content/msls-1.0.1.min.css" />
そして、scriptタグもバージョン番号を変えるのとjsRenderのJavaScriptを読み込むようにします。
<scripttype="text/javascript"src="//ajax.aspnetcdn.com/ajax/globalize/0.1.1/globalize.min.js"></script><scripttype="text/javascript"src="Scripts/winjs-1.0.min.js"></script><scripttype="text/javascript"src="Scripts/jquery-1.9.1.min.js"></script><scripttype="text/javascript"src="Scripts/jquery.mobile-1.3.1.min.js"></script><scripttype="text/javascript"src="Scripts/datajs-1.1.0.min.js"></script><scripttype="text/javascript"src="Scripts/Generated/resources.js"></script><scripttype="text/javascript"src="Scripts/msls-1.0.1.min.js"></script><scripttype="text/javascript"src="Scripts/Generated/generatedAssets.js"></script><scripttype="text/javascript"src="Scripts/jsviews.min.js"></script>
データの作成
とりあえず簡単にデータを定義します。NameとAgeを持っただけのシンプルなデータです。
こいつを表示するためのBrowseページと編集追加する画面を適当に定義します。そして、その画面を使って4件くらいデータを入れました。
jsRenderで遊ぶ
ついに本題です。jsRenderで遊びましょう。Personとして定義したデータを表示したいので、NameとAgeを持つテーブルの行を表示するテンプレートをdefault.htmに以下のように定義してみました。
<!-- テーブルのヘッダー部のテンプレート(固定テキストだからテンプレートにする必要性はないかも?) --><scriptid="personHeaderRowTemplate"type="text/x-jsrender"><tr><th>名前</th><th>年齢</th></tr></script><!-- Personをテーブルの行として展開するテンプレート。名前はHTMLエンコードする --><scriptid="personRowTemplate"type="text/x-jsrender"><tr><td>{{html:Name}}</td><td>{{:Age}}</td></tr></script><!-- Personの配列をテーブルの行として展開するテンプレート --><scriptid="personRowsTemplate"type="text/x-jsrender">{{for rows tmpl="#personRowTemplate"/}}</script>
最初のはヘッダー。あとはテーブルのボディ部です。最後のテンプレートでforを使って複数行のデータの展開にも対応しています。テンプレートの定義ができたので、default.htmのreadyメソッドで、テンプレートを読み込んでおきます。
<scripttype="text/javascript"> $(document).ready(function(){// テンプレートを読み込んでおく $.templates("personHeaderRowTemplate", "#personHeaderRowTemplate"); $.templates("personRowTemplate", "#personRowTemplate"); $.templates("personRowsTemplate", "#personRowsTemplate"); msls._run() .then(null, function failure(error){alert(error);});});</script>
あとはBrowseのページにタブを新規追加して、そこにPersonSetのデータをレンダリングするカスタムコントロールを定義してレンダリング処理をかいていきます。ここらへんは定型句なんですが、jsRenderのおかげで退屈なHTML組み立て処理がかなりすっきりしています。
ちょっと困ったのは、jsRenderで作ったHTMLを$()に食わせるとエラーになったのでdivタグを作って、そこに流し込んでcontentsでjQueryのオブジェクトとして取り出しています。
*3
/// <reference path="../GeneratedArtifacts/viewModel.js" />/// <reference path="../Scripts/jsviews.min.js" /> myapp.BrowsePersonSet.PersonSet_render = function (element, contentItem) {var $element = $(element); // テーブルの骨組みを組み立てる。jquery mobileのテーブルを使うvar table = $('<table id="peopleTable" data-role="table" class="ui-responsive"/>') .appendTo($element); // ヘッダvar headerHtml = $.render.personHeaderRowTemplate(); $('<thead />') .html(headerHtml) .appendTo(table); // ボディvar tbody = $('<tbody />').appendTo(table); var c = contentItem.value; // コレクションのデータをレンダリングするif (c.isLoaded) { renderRows(tbody, c.data); return; } c.addChangeListener("isLoaded", function () { renderRows(tbody, c.data); }); }; // tbodyにrowsで渡されたデータを追加するfunction renderRows(tbody, rows) {var rowsHtml = $.render.personRowsTemplate({ rows: rows }); $('<div />') .html(rowsHtml) .contents() .appendTo(tbody); } myapp.BrowsePersonSet.loadMorePeople_canExecute = function (screen) {// データに続きがある場合は読み込めるreturn screen.PersonSet.canLoadMore; }; myapp.BrowsePersonSet.loadMorePeople_execute = function (screen) {// データの続きを読み込み、tbodyにデータを追加する screen.PersonSet.loadMore().then(function (r) { renderRows($('#peopleTable tbody'), r.items); }); };
最後の2つのメソッドは、カスタムコントロールの下に置いたボタンの処理で、続きのデータがあったら読み込むといった処理になってます。
最後に、データの続きを読む処理を試すためにPersonSetの取得件数をプロパティから3件に減らしておきます。
実行してみよう
アプリを実行したら、データの読み込みが終わる前に素早くタブ切り替えをしてテーブルを表示してるタブに移動します。そうするとテーブルにデータが3件表示されています。
続きを読み込むボタンを押すと、続きのデータが読み込まれます。今回はデータを4件しか作ってないので、これ以上データがないのでボタンが消えます。(無効化したら消えるように設定してたんだった)
まとめ
- LightSwitchのカスタムコントロールでjQuery mobileのコントロールの実験とかやると面白い。
- jsRenderはいいテンプレートエンジンだ。
- LightSwitchは、結構JavaScriptで何でもできそう
- JavaScriptはインテリセンスあるとはいえC#に比べたら貧弱で辛い