Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

LightSwitch(HTML Client)でjsRenderを使ってテーブルを表示してみた

$
0
0

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を持っただけのシンプルなデータです。
f:id:okazuki:20130807232137p:plain
こいつを表示するためのBrowseページと編集追加する画面を適当に定義します。そして、その画面を使って4件くらいデータを入れました。
f:id:okazuki:20130807232607p:plain

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件表示されています。

f:id:okazuki:20130807233735p:plain
続きを読み込むボタンを押すと、続きのデータが読み込まれます。今回はデータを4件しか作ってないので、これ以上データがないのでボタンが消えます。(無効化したら消えるように設定してたんだった)
f:id:okazuki:20130807233933p:plain

まとめ

  • LightSwitchのカスタムコントロールでjQuery mobileのコントロールの実験とかやると面白い。
  • jsRenderはいいテンプレートエンジンだ。
  • LightSwitchは、結構JavaScriptで何でもできそう
  • JavaScriptはインテリセンスあるとはいえC#に比べたら貧弱で辛い

*1:悲しいけど機械翻訳

*2:今度は自作テーマあててみようかな

*3:ここを参考にしました。http://stackoverflow.com/questions/11047670/creating-a-jquery-object-from-a-big-html-string


Viewing all articles
Browse latest Browse all 1387

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>