先日CSSNite LP18に参加したのですが、中でも一際気になったjQuery Templateの機能を掘り下げたいと思います。

jQuery Template?

利点

これを使うと何が嬉しいかというと、表示のためのHTMLとロジック処理のためのJacaScriptをきちんと分離出来るということが挙げられます。 (※ちなみに、まだbetaです)

サンプル

例えば、こんなHTMLがあったとします。 サーバーサイドからある書籍のリストをAjaxでロードしてリスト表示します。

<div>
    <h4>書籍タイトル</h4>
    <dl id="bookList">
    <!--
        <dt>逆襲ノマド</dt>
        <dd>新しい仕事</dd>
        <dt>黄昏サスペンデッド</dt>
        <dd>今日は早く帰ろう</dd>
        <dt>やる気 not Fount!</dt>
        <dd>ノーコメント</dd>
    -->
    </dl> 
</div>
マークアップをした人はコメントアウトしている箇所をdt+ddの定義リストで表示することを想定しています。 一方JavaScript側ではこのような記述をしているようです。

<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.5.2.js"></script>
<script type="text/javascript">

/*
 *    Ajax処理の結果
*/
var result = [
        { "title":'逆襲ノマド',               "description": '新しい仕事'     },
        { "title":'黄昏サスペンデッド',   "description": '今日は早く帰ろう'  },
        { "title":'やる気 not Fount!',    "description": 'ノーコメント'      }
    ];

(function($){
    $( "#load" ).click(function(e){

        //result = Ajax処理の結果とか
        var jsonAray = result;

        var bookList = "";
        for (var i = 0; i < jsonAray.length; i ++) {
            var book = jsonAray[i];
            bookList += "<tr>";
            bookList += "<td>" + book.title + "</td>";
            bookList += "<td>" + book.description + "</td>";
            bookList += "</tr>";
        }

        $("#bookList").append( bookList );
    });
})(jQuery);
</script>
定義リストを(dl要素)想定しているのにテーブルのtr要素で返って来ました。 これは、はなから構築するHTMLをちゃんと打ち合わせしていないので例が悪いですが、JavaScriptのロジック中に要素を直書きしているのが原因です。 dt+dd要素にspan要素を追加してidを振り、一つずつ値を設定すれば、JacaScriptの処理中にhtmlタグを記述せずに済みそうですが数が多くなると大変です。 また、後からこの書籍の定義リストをやはりtable要素に変更したいという事になったとします。 これぐらいの規模ならさっと変更箇所を探せますが、複雑な処理を行なっているJavaScriptのコードにポツンとdt+dd要素があったりして、どの部分のコードなのかが分からなかったりします。 そこで、jQuery Templateを使ってこのようにHTMLを記述します。

<div>

       <h4>書籍タイトル</h4>

    <dl id="bookList2">
    <script id="bookList2Tmpl" type="text/x-jquery-tmpl">
        <dt>${title}</dt>
        <dd>${description}</dd>    
    </script>
    </dl>
</div>
dt+dd要素をhtml側に記述しているのがわかります。 使い方としては script要素の type属性 に "text/x-jquery-tmpl"を記述し、idを振ります。 Ajaxで取得することが予想される書籍リストの情報、Jsonオブジェクト(オブジェクトリテラル)のプロパティ(今回は${title}や${description})を記述しておきます。 Ajaxで取得したデータをテンプレート(id="bookListTemple")に割り当てるJavaScriptのコードはこのようになります。

<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.5.2.js"></script>
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.js"></script>

<script type="text/javascript">

/*
 *    Ajax処理の結果
*/
var result = [
        { "title":'逆襲ノマド',        "description": '新しい仕事'    },
        { "title":'黄昏サスペンデッド', "description": '今日は早く帰ろう'    },
        { "title":'やる気 not Fount!',   "description": 'ノーコメント'       }
    ];

(function($){
    $( "#loadTmpl" ).click(function(e){

        // テンプレートの記述場所によっては注意が必要
        // (scriptタグごと消える)
        //$("#bookList2").children().remove();

        //result = Ajax処理の結果とか
        var jsonAray = result;

        var bookList = $( "#bookList2Tmpl").tmpl( jsonAray );

        $("#bookList2").append( bookList );

    });
})(jQuery);
</script>
これでJsonデータのプロパティさえしっかり割り当てていれば、デザイン側の編集は簡単に行うことができます。 今回は配列に複数個の書籍データを同じプロパティ名で指定していますが、このあたりは上手く複数個(ループ)処理してくれるようです。 本当はテンプレート内にdl要素を記述できればいいのですが、同一プロパティを複数個割り当てる場合は、子要素のみの記述になりそうです。 また、この例では追加するdl要素内にscriptタグを記述していますが、DOM操作に注意が必要です。 例えば、dl要素内のdt+dd要素をクリアするつもりで

$("#bookList2").children().remove();
と記述すると、dl要素内のscriptも無くなってしまいます。 この場合はちょっと視認性が落ちますが、head内に移動するなどの必要がありそうです。

サンプルデモ

jQuery Templeteのデモ

考察

最近、特にJavaScript上からAjaxなどでデータを取ってくる事が多く、しかも構造が複雑になってきているので、jQuery Templeteを上手く使いこなせば相当コードの見通しが良くなると思います。 なにより、表示と処理ロジックが分離出来るということはデザイナーさんと分業する場合に非常に効果的だと思いました。