0

名前でソートされた連絡先の配列を想像してみてください。この配列は次のように出力できます。

<ul data-bind="foreach: contacts>
    <li data-bind="text: name"></li>
</ul>

私がやりたいのは、異なる開始文字を持つ各liの見出しを指定することです。たとえば、A、B、D..を表示します。

- A
- Anderson
- Andrews
- B
- Bellamy
- D
- Davidson
- Davis

通常のプログラミング言語では、名前の最初の文字を含む変数を定義し、foreachループ内でそれが異なるかどうかを確認します。その場合は、ヘッダーを表示します。

knockout.jsでこれをどのように行う必要がありますか?

4

2 に答える 2

1

これがノックアウトパターンに固執する方法です。最初に、文字でグループ化された新しい配列に配列をマップする計算されたオブザーバブルを作成します。

self.contactsByLetter = ko.computed(function () {
    var result = [],
        currentLetter, currentGroup;
    ko.utils.arrayForEach(self.contacts(), function (contact) {
        if (contact.name[0] !== currentLetter) {
            currentLetter = contact.name[0];
            currentGroup = {
                letter: currentLetter,
                contacts: []
            }
            result.push(currentGroup);
        }
        currentGroup.contacts.push(contact);
    })
    return result;
});

次に、HTMLに必要なループは2つだけです。

<ul data-bind="foreach: contactsByLetter">
    <li class="heading" data-bind="text: letter"></li>
    <!--ko foreach: contacts-->
    <li data-bind="text: name"></li>
    <!--/ko-->
</ul>

jsFiddle: http: //jsfiddle.net/mbest/ZcQT4/

于 2013-02-14T21:36:58.207 に答える
0

よりクリーンな方法かどうかはわかりませんが、文字に固定配列を使用してから、ビューモデルのメソッドを使用して、n番目の文字で始まるアイテムのみを返すことができます。

<ul data-bind="foreach: letters">
    <li data-bind="text: $data">
        <ul data-bind="foreach: $parent.contactsStartingWith($data)">
             <li data-bind="text: name"></li>
        </ul>
    </li>
</ul>

ここで、contactsStartingWithは次のように定義できます。

function(start) {
    return ko.utils.arrayFilter(contacts(), function(it) { return it.name()[0].toUpperCase() == start } );
}

...そして文字配列は次のように簡単に抽出できます:

viewModel.letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");

(配列を操作するノックアウトユーティリティのいくつかの便利なリファレンス:http ://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html )

于 2013-02-14T21:32:22.907 に答える