想象一下按名称排序的联系人数组。 该数组可以输出如下:
<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?
答案 0 :(得分:1)
这是一种坚持Knockout模式的方法。首先,您将创建一个计算的observable,将您的数组映射到一个按字母分组的新数组。
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只需要两个循环。
<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/
答案 1 :(得分: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("");
(使用数组的knockout工具的一些有用的参考:http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html)