Edited at

複雑なHTMLを動的にロードするとき,JSテンプレートを利用するとよい

More than 5 years have passed since last update.

完全に遅れてしまっていてもはやAdvent Calendarではなくなっている「Backbone.js Advent Calendar」ですが,なんとか25日まで続けます:)

ちなみに昨日までの「Backbone.js入門」シリーズ(by @taka84u9)がとてもわかりやすいので,Backbone.jsを使ったことのない人はまずそちらから読むのがおすすめです.

(http://qiita.com/adcal/backbone の12/11分より)


はじめに

Ajaxを利用して動的にHTMLをロードするとき,対象HTMLが複雑になってくるとJSだけで作るのはコストが大きくなってきます.(appendの山)

またぱっとコードを見たときにどういうHTMLになるかわからず,デザイナーと共同作業もやりにくくなります.タグを1つ追加したいだけなのに,JSのコードを読んで追加処理を書くのはかなり面倒です.


JavaScriptテンプレート

そこでJSテンプレート,例えばjQuery template(beta)mustache.jsunderscore.jsの_.templateなどを利用するとこうした問題を解決できます.

以下は_.templateの使い方です.(underscore.jsのドキュメントより引用)

var list = "<% _.each(people, function(name) { %> <li><%= name %></li> <% }); %>";

_.template(list, {people : ['moe', 'curly', 'larry']});
// => "<li>moe</li><li>curly</li><li>larry</li>"

実際はこのようにテンプレート内容を文字列で渡すのではなく,以下のように別セクションに分けて記述すると思います.

<script type="text/template" id="my-template">

// テンプレート内容
</script>
<script type="text/javascript">
_.template($('#my-template').text(), data); // => html
</script>


ちょっとした工夫(キャッシュ)

TwitterやQiitaのようなストリームタイプのページでは,テンプレート化したいブロックが1ページ内に何度も出てきます.そこでテンプレートを利用するときに,アイテムごとに同じテンプレートを毎回JSで処理するのは無駄です.

そこで以下のようにテンプレート処理後のデータをキャッシュしておくことで,処理を1度だけ行わせることができます.ここではunderscore.jsの_.templateを利用しています.

(underscore.jsについてはunderscore.js入門をどうぞ)

// テンプレートの処理は1度だけ実行される

if ($('#my-template').length) {
templateCache['my-template'] = _.template($('#my-template').html());
}

var myView = Backbone.View.extend({
template: templateCache['item-box-template'],
// ...
});

以上,JSテンプレートのすすめ&ちょっとした工夫でした.(あんまりBackbone.jsに関係ない…)