wataメモ

日々のメモをつらつらと書くだけ

[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>