[4][JavaScript]google-jstemplateを使ってみる
いつもAjaxで情報を取得して、画面に出す時に、jsonでデータを返して貰った方がJavaScript上では扱いやすい。しかし、デザインを当てるためにHTMLタグに組み込む場合にJavaScriptでゴリゴリHTMLエレメントを作っていくのはメンテナンス性が悪くなってしまう。その為、Ajaxでjsonではなく「HTMLにした」情報を返してもらって、単純に埋め込むだけと言うのを良くやっていた。これはデザインをサーバサイドのテンプレート(JSP等)に集約して、保守性を上げる意味もあった。
サーバサイドとテンプレートを共存させる必要が無い場合や、外部のAPIの場合はjsonを返してくる場合にHTML化する処理でループとか分岐とかを使えるJavaScriptテンプレートがあると良いなとはよく思っていた。jquery-tmpl等もあるが、今回はgoogleが出したというgoogle-jstemplateを使ってみる事にした。
まず、ダウンロードしようと思ったがサイト上ではダウンロードリンクはなく、subversionでチェックアウトする必要があった。
svn checkout http://google-jstemplate.googlecode.com/svn/trunk/ google-jstemplate-read-only
使ってみようとすると他のライブラリと違って3つ読み込む必要があった。DLを提供する様になったら、1つに纏めてくれないものかなぁ。
<scriptsrc="util.js"type="text/javascript"></script>
<scriptsrc="jsevalcontext.js"type="text/javascript"></script>
<scriptsrc="jstemplate.js"type="text/javascript"></script>
Quick Exampleを見るとJsEvalContextにデータを渡してnewして、テンプレートのHTMLをgetElementByIdで取得したやつを、jstProcess関数に渡せば動くようだ。ただ、getElementByIdで取得したのを渡すと、そこのHTMLが書き変わってしまうので、jstGetTemplate(templateElementId)関数で取れば元のHTMLをcloneしたのが返ってくるので、テンプレートを変更しないように出来る。テンプレートを使って複数個生成する場合はこちらを使うことになる。そして、cloneしたDOMは所定の場所にappendChildする必要がある。テンプレートはHTML上に書いておくので、style="display: none;"しておく。ループ、表示非表示の分岐(jsdisplay属性)、2つのテンプレート間で一部のテンプレートの共有(transclude)等かなり高機能。しかし、これは分かりづらい・・・。ある程度慣れないと思うようには出来ないので、導入に若干の問題ありか。これはmayaaを学んでいた時の感覚と同じだった。
とりあえずテーブルを作るには以下のような感じ。
<html> <head> <script type="text/javascript" src="http://www.google.com/jsapi"></script> <script type="text/javascript">google.load('jquery', '1');</script> <script type="text/javascript" src="js/util.js"></script> <script type="text/javascript" src="js/jsevalcontext.js"></script> <script type="text/javascript" src="js/jstemplate.js"></script> <script type="text/javascript"> var data = { dat: [{'id': '1', 'name': 'name1'}, {'id': '2', 'name': 'name2'}] }; function showTable(data) { var input = new JsEvalContext(data); var o = jstGetTemplate('t'); jstProcess(input, o); $('#o').append(o); } $(document).ready(function() { showTable(data); }); </script> </head> <body> <div id="o" /> <div style="display: none;"> <table id="t"> <tbody> <tr jsselect="dat"> <td jscontent="id"></td> <td jscontent="name"></td> </tr> </tbody> </table> </div> </body> </html>