Jquery 给出一个淘汰模型,思考如何生成字母索引

Jquery 给出一个淘汰模型,思考如何生成字母索引,jquery,knockout.js,Jquery,Knockout.js,我有一个联系人列表,如: 1 Mon Bob Brett Brad Kathy Zelda 在应用模型或使用jQuery模板后,使用KnockoutJS可以很容易地显示该列表 我现在感兴趣的是动态显示标题,就像它在iPhone上的工作方式一样,这意味着输出将如下所示: # 1 Mon B Bob Brett Brad K Kathy Z Zelda 有没有想过如何巧妙地完成这一任务,而不必为每个字母数字硬编码一个标题? 自然分类,以防它们尚

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

  1 Mon
  Bob
  Brett
  Brad
  Kathy
  Zelda
在应用模型或使用jQuery模板后,使用KnockoutJS可以很容易地显示该列表

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

#
  1 Mon
B
  Bob
  Brett
  Brad
K
  Kathy
Z  
  Zelda
有没有想过如何巧妙地完成这一任务,而不必为每个字母数字硬编码一个标题?

  • 自然分类,以防它们尚未分类
  • 创建新对象以保存新数据
  • 循环遍历已排序的数组,为遇到的每个新组创建一个数组
  • 根据联系人的组追加联系人

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

此外,如果您想为<代码> > < <代码> >代码> A.Z/<代码>创建空白数组,只需循环遍历<代码> > abcFdgjnjopopqrStuvvxyz′。


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

我在KO论坛上回答了您的问题:

此处示例:

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

DependentToServable看起来像:

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);

@A根据您的要求创建分组的联系人。然后你可以遍历它并构建任何HTML。谢谢,这非常干净。如果不知道数组中有什么内容,您如何在数组上循环?@AnApprentice如果您指的是结果数组,您可以使用jQuery。contactsGrouped在做什么?@AnApprentice只是一个具有某些属性的对象。我猜只是闲逛,等待有人重复:)你可以让任何一种方法都有效。我的答案是供模板中的敲除使用的。his的结果是每个字母都有属性的对象。我的结果是一个数组,您可以轻松地使用KO中模板绑定的foreach选项(foreach不会循环遍历对象的属性)。这就是代码稍微多一些的原因。我还假设你的联系人是对象,而不是字符串数组。他们应该被排序。它和我的小提琴有什么不同吗:我更新了排序。应该对字母执行toUpperCase()并返回-1或1。如果您需要帮助来处理名称为空的问题,请告诉我。我想您可以用几种方法来处理它。在不引入新变量的情况下,只需将排序更改为:var sortedContacts=this.contacts().sort(函数(a,b){return(a.name()| |“”).toUpperCase()>(b.name()| |“”).toUpperCase()?1:-1;});并在contacts://grab first character var firstLetter=(contact.name()| |“”).charAt(0.toUpperCase())的循环中执行此操作;Fiddle updated:我更新了我的Fiddle,更改了排序函数:。不确定你是否从另一个问题中得到了答案。
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);