読者です 読者をやめる 読者になる 読者になる

ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

WinJS.UI.ListView の項目に何番目の要素であるかを表示する

JavaScript Windows ストアアプリ WinJS

WinJS.UI.ListView に表示する項目に、その項目のインデックスやグループ内の項目数を表示する方法として WinJS.Binding.Template.prototype に手を加えるという記事を見かけました。

この方法よりも、WinJS.UI.ListView#itemTemplate プロパティWinJS.UI.ListView#groupHeaderTemplate プロパティにテンプレートとなる関数を設定し、その関数の中で項目のインデックスなどを取得した方が良さそうだと思ったのでその方法について書いておきます。

WinJS.UI.ListView#itemTemplate プロパティや WinJS.UI.ListView#groupHeaderTemplate プロパティ

下記記事で詳しく説明しましたが、WinJS.UI.ListView#itemTemplate プロパティには WinJS.Binding.Template オブジェクト (に対応する HTML 要素) だけでなく、関数を設定することもできます。 WinJS.UI.ListView#groupHeaderTemplate プロパティも同様です。

その関数の第 1 引数には、WinJS.UI.IItemPromise インターフェイスを実装したオブジェクトが渡されます。 このオブジェクトは Promise で wrap されているわけですが、中身の値は WinJS.UI.IItem インターフェイスを実装したオブジェクトであり、このオブジェクトは項目のインデックス (index プロパティ) などの情報をもっています。 なので、関数の中でそれらを取り出して使用することができます。

ドキュメントには書かれていませんが、グループのリストの項目の場合は groupSize プロパティにグループ内の項目数をもっています *1。 グループ内の項目数を表示したい場合はこのプロパティを参照すればいいでしょう。

サンプル

HTML 側では以下のように宣言的に WinJS.UI.ListView コントロールを定義しておきます。

<div data-win-control="WinJS.UI.ListView" id="listview"></div>

JavaScript 側では、HTML で定義した ListView コントロールにテンプレート関数を設定し、グループ化したリストを結び付けます。

var listView = document.getElementById("listview").winControl;

listView.itemTemplate = function (itemPromise) {
    // itemPromise は WinJS.UI.IItemPromise インターフェイスを実装したオブジェクト
    return itemPromise.then(function (item) {
        // item は WinJS.UI.IItem インターフェイスを実装したオブジェクト
        var elem = document.createElement("div");
        elem.textContent = item.data.name + " - 項目のインデックス : " + item.index;
        return elem;
    });
};
listView.groupHeaderTemplate = function (itemPromise) {
    // itemPromise は WinJS.UI.IItemPromise インターフェイスを実装したオブジェクト
    return itemPromise.then(function (item) {
        // item は WinJS.UI.IItem インターフェイスを実装したオブジェクト
        var elem = document.createElement("div");
        elem.textContent =
            item.data + " - " +
            "グループのインデックス : " + item.index + ", " +
            "グループ内の項目数 : " + item.groupSize;
        return elem;
    });
};

// ListView オブジェクトに結びつけるリストの生成
var list = new WinJS.Binding.List([
    { groupId: "人", name: "シンジ" },
    { groupId: "動物", name: "猫" },
    { groupId: "人", name: "カヲル" },
    { groupId: "動物", name: "ペンペン" }
]);

// list をグループ化して, listView に結び付ける
var groupedList = list.createGrouped(
    function (dat) { return dat.groupId },
    function (dat) { return dat.groupId }
);
listView.itemDataSource = groupedList.dataSource;
listView.groupDataSource = groupedList.groups.dataSource;

これを実行すると、以下のようになります (CSS は適当にいじっています)。

f:id:nobuoka:20121122004223p:plain

*1:ドキュメントにはありませんが、List.createGrouped メソッドのサンプルコードの中で使用されているので、使用してもよかろうと思います。