2011-05-01 39 views
2

想法我有這樣的聯繫人列表:鑑於淘汰賽模式,對如何生成字母索引

1 Mon 
    Bob 
    Brett 
    Brad 
    Kathy 
    Zelda 

這是一個與KnockoutJS很容易將模型應用或使用jQuery的模板後,顯示該列表。

什麼我有興趣做,現在是動態顯示標題,如:它的工作原理iPhone上的方式,這意味着輸出將如下所示:

# 
    1 Mon 
B 
    Bob 
    Brett 
    Brad 
K 
    Kathy 
Z 
    Zelda 

如何巧妙地敲做到這一點有什麼想法無需爲每個字母數字硬編碼標題?

回答

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

感謝RP,它看起來不錯,但我認爲亞歷克斯的解決方案是一個更清潔。想法? – AnApprentice 2011-05-01 03:09:57

+1

你可以讓任何一種方式工作。我的答案旨在供模板中的Knockout使用。他的結果是每個字母都有屬性的對象。我的結果是一個數組,您可以輕鬆地使用KO中的模板綁定的foreach選項(foreach不會循環通過對象的屬性)。這是更多代碼的原因。我還假設你的聯繫人是對象而不是一串字符串。 – 2011-05-01 03:23:43

+0

良好的通話。現在嘗試。到目前爲止,錯誤是,如果name爲null,那麼給出聯繫人列表(firstname,lastname,email)的錯誤是可能的。另外由於某些原因,當您輸出contactsModel.contactsByLetter()時,頭文件不會排序,顯示YZG,而不是#,A,B,E,Z等.... – AnApprentice 2011-05-01 03:28:40

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()方法即可。

+0

@AnApprentice它創建您的要求下分組的聯繫人。然後,您可以遍歷它並構建任何HTML。 – alex 2011-05-01 03:07:19

+0

非常感謝你的乾淨。你將如何遍歷數組,不知道數組中有什麼? – AnApprentice 2011-05-01 03:09:25

+1

@AnApprentice如果你的意思是結果數組,你可以使用jQuery ['.each()'](http://api.jquery.com/jQuery.each/)。 – alex 2011-05-01 03:10:41