给出一个淘汰模型,关于如何生成字母索引的想法

时间:2011-05-01 01:37:40

标签: jquery knockout.js

我有一个联系人列表,如:

  1 Mon
  Bob
  Brett
  Brad
  Kathy
  Zelda

使用KnockoutJS很容易在应用模型或使用jQuery模板后显示该列表。

我现在感兴趣的是动态显示标题,就像它在iPhone上的工作方式一样,意味着输出看起来像:

#
  1 Mon
B
  Bob
  Brett
  Brad
K
  Kathy
Z  
  Zelda

有关如何使用Knockout巧妙地完成此操作的任何想法,而不必对每个字母数字进行硬编码?

2 个答案:

答案 0 :(得分:4)

我在KO论坛上回答了您的问题:https://groups.google.com/d/topic/knockoutjs/VgDnxb_jB7c/discussion

此处示例:http://jsfiddle.net/rniemeyer/MZN6u/

我创建了一个dependentObservable,其结构可以轻松映射到视图(模板),这是一个对象数组,每个对象都有letter属性和contacts数组。

dependentObservable看起来像:

viewModel.contactsByLetter = ko.dependentObservable(function() {
    var letterIndex = [];
    var result = [];
    //sort the contacts
    var sortedContacts = this.contacts().sort(function(a, b) {
      return a.name().toUpperCase() > b.name().toUpperCase() ? 1 : -1; 
    });
    //loop through each contact and put it with its letter
    ko.utils.arrayForEach(sortedContacts, function(contact) {
        //grab first character
        var firstLetter = contact.name().charAt(0).toUpperCase();
        //if it is a number use #
        if (!isNaN(firstLetter)) {
            firstLetter = "#";
        }

        //do we already have entries for this letter
        if (!letterIndex[firstLetter]) {
            //new object to track this letter's contacts
            var letterContacts = {
                letter: firstLetter,
                contacts: []
            };
            letterIndex[firstLetter] = letterContacts ; //easy access to it
            result.push(letterContacts); //add it to the array that we will return
        }

        //at this point we should have an object to push our contact to
        letterIndex[firstLetter].contacts.push(contact);
    });

    return result;
}, viewModel);

答案 1 :(得分:3)

  • 自然排序,以防它们尚未存在。
  • 创建一个新对象以保持新数据的有序化。
  • 遍历已排序的数组,为遇到的每个新组创建一个数组。
  • 根据群组附加联系人。
contacts.sort();
var contactsGrouped = {};
$.each(contacts, function(index, contact) {
   var first = contact.substr(0, 1),
       group = first.match(/\d+/) ? '#' : first;

  if (contactsGrouped[group] === undefined) {
      contactsGrouped[group] = [];
  }

  contactsGrouped[group].push(contact);
});

jsFiddle

如果您不确定联系人上是否有前导/尾随空格,可能值得调用$.trim()

此外,如果要为#a-z创建空白数组,只需先遍历'#abcdefghijklmnopqrstuvwxyz'.split('')并设置空白数组。

此外,如果您希望属性为大写,只需在设置属性之前调用toUpperCase()方法。