Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

JsViewsチュートリアル - データリンクされた配列データを操作する

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。
以前に書いたエントリJsViews入門 - Do You PHP はてなも参照してください。

今回やること

JsViewsでデータリンクされた配列データに対して追加・削除などの操作をする

コード

<html>
<body>

<!-- レンダリング結果を表示するスペース -->
<div id="result_link"></div>
<hr/>
<div id="result_link_for"></div>

<a href="#" id="add">add</a>

<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://www.jsviews.com/download/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
// 配列の操作
$(function() {
    // データの配列(もしくはオブジェクト)
    var fruits = [
        { name: "りんご", num: 3 },
        { name: "いちご", num: 5 },
        { name: "バナナ", num: 2 },
    ];

    // テンプレートに名前をつけて登録する
    // linkForTemplateはデータリンクしたforタグを使ったテンプレート
    $.templates({
        linkTemplate: "#template",
        linkForTemplate: "#template_for"
    });

    // テンプレート"linkTemplate"と変数fruitsをリンク
    $.link.linkTemplate('#result_link', fruits);
    $.link.linkForTemplate('#result_link_for', {fruits: fruits});

    $(document)
        /**
         * "add"をクリックすると、配列データに新しいデータを
         * 追加して再レンダリング
         */
        .on('click', '#add', function(ev) {
            // リンクされた配列データへの追加は$.observable().insert()
            $.observable(fruits).insert(
                { name: "ドリアン", num: fruits.length }
            );
            ev.preventDefault();
        })
        /**
         * "×"をクリックすると、配列データから当該データを
         * 削除して再レンダリング
         */
        .on('click', '.remove', function(ev) {
            // リンクされた配列データから削除は$.observable().remove()
            $.observable(fruits).remove(
                // clickイベントが発生したViewオブジェクトを取得し、
                // そのindexを取得する
                $.view(this).index
            );
            ev.preventDefault();
        });
});
</script>

<!-- テンプレート -->
<script id="template" type="text/x-jsrender">
    <p>{^{>#index}}:{{:name}}{{:num}}個あります <a href="#" class="remove">×</a></p>
</script>
<script id="template_for" type="text/x-jsrender">
{^{for fruits}}
    <p>{^{>#index}}:{{:name}}{{:num}}個あります <a href="#" class="remove">×</a></p>
{{/for}}
</script>
</body>
</html>

説明

前回までのチュートリアルでは、テキストボックスに値を入力することでデータリンクした値を更新していましたが、当然JavaScriptコード内からデータを更新したい場合もあります。
例えば配列データの場合、

fruits.push({ name: "ドリアン", num: 4 });

などとやっても、JsViewsにはデータが更新されたかどうか判断できません。逆に、リンクの情報を壊してしまう結果になります。JsViewsでは、配列やオブジェクトを更新するための仕組みが提供されています(実際にはJsObservableという別ライブラリ)ので、これを使うことになります。配列データの更新については、追加・削除・移動・全更新の4つが用意されています。

追加

配列データの任意の場所、もしくは最後にデータを追加します。

$.observable([データリンクした配列データ]).insert([追加するデータの位置], [追加するデータ])

追加するデータの位置は配列の添字(0始まり)です。省略可能でその場合は最後に追加されます。
コード例では、"add"というリンクをクリックした際に、変数fruitsの最後にオブジェクトを追加しています。

$.observable(fruits).insert({ name: "ドリアン", num: fruits.length });
削除

配列データの任意の場所のデータを削除します。

$.observable([データリンクした配列データ]).remove([削除するデータの位置], [削除するデータの数])

削除するデータの位置は配列の添字(0始まり)で、削除した位置より後ろのデータは前に詰められます。削除するデータ数は省略した場合は1となります。
コード例では、"×"というリンクをクリックした際に、当該データを変数fruitsから削除しています。

$.observable(fruits).remove($.view(this).index);
移動

配列データの任意の場所のデータを任意の場所に移動します。

$.observable([データリンクした配列データ]).move([移動するデータの位置], [移動先の位置], [移動するデータの数])

移動するデータの位置と移動先の位置は配列の添字(0始まり)です。移動するデータの数を省略した場合は1となります。

全更新

配列データをすべて入れ替えます。

$.observable([データリンクした配列データ]).refresh([新しい配列データ])

JSFiddleで動作を見る