このサイトの記事ではいままで knockout のバインディングの機能を使用するときに毎回その場で ビューモデルとバインドするマークアップの定義をバインドする場所に記載していました。このようにすると、似たようなバインディングの定義でも毎回そのマークアップを記載する必要があります。このように似たような定義をいろいろな場所に記載してしまうと変更が発生した際にいろいろな場所で変更を反映する必要が発生し、保守性を悪くしてしまいます。knockoutJSはtemplateバインディングを使用して生成するマークアップ(レンダリング)の部分をテンプレート化して再利用可能にすることでこの問題を解決できるようになっています。今回の記事では templateバインディングを使用する覚書を記載します。

検証は KnockoutJS 3.3 で行いました。

1. templateバインディングを使用する

さっそく template バインディングを使用してみます。templateバインディングのnameパラメーターに<script type="text/html"> でテンプレートを定義したscriptタグの id を 指定して使用するテンプレートを設定しています。foreachパラメーターでバインドするビューモデルオブジェクトのコレクションを指定しています。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>templateバインディングを使用してマークアップを再利用可能にする</title>
</head>
<body>
    <table>
        <thead>
            <tr>
                <th>名前</th>
                <th>URL</th>
                <th>メモ</th>
            </tr>
        </thead>
        <tbody data-bind="template: { name: 'searchengine-template', foreach: searchEngines}"></tbody>
    </table>
    <script type="text/javascript" src="/Scripts/knockout-3.3.0.js"></script>
    <script type="text/html" id="searchengine-template">
        <tr>
            <td data-bind="text: name"></td>
            <td><a data-bind="attr: {href:url}, text:url"></a></td>
            <td data-bind="text: remark"></td>
        </tr>
    </script>
    <script type="text/javascript">
        function ViewModel() {
            var self = this;

            self.searchEngines = [
                {
                    name: 'Yahoo!',
                    url: 'http://www.yahoo.co.jp',
                    remark: 'ヤーホー'
                }, {
                    name: 'Bing',
                    url: 'http://www.bing.com',
                    remark: 'ビン'
                }, {
                    name: 'Google',
                    url: 'http://www.google.co.jp',
                    remark: 'ゴーゴ'
                }
            ];
        };

        var vm = new ViewModel();
        ko.applyBindings(vm);
    </script>

</body>
</html>

2.まとめ

簡単ですがサンプルの紹介は以上です。
今回の例ではforeachバインディングを使用して コレクション(配列)に対してテンプレートを適用しましたが、 data や nodes なども指定できますので詳細は knockoutJS の公式ドキュメントのページを参照してください。