2015-06-08 22 views
1

我試圖按obervableArray的兩項進行排序。我在http://jsfiddle.net/organa7/yyy3y2ka/上創建了這個簡化版本。通過多個參數對oberservableArray進行排序

Line Group Id 
<select data-bind="options: lineGroupIds, optionsValue: 'value', optionsText: 'text', value: selectedGroupId"> 
</select> 

Line Type 
<select data-bind="options: lineTypes, optionsValue: 'value', optionsText: 'text', value: selectedLineType"> 
</select> 

<button data-bind="click: addLine">Add Line</button> 
</br> 
Line Count:&nbsp;<span data-bind="text: lines().length"></span> 
</br> 
<table> 
    <thead> 
     <tr> 
      <th>Line Group Id</th> 
      <th>Line Type</th> 
     </tr> 
    </thead> 
<tbody data-bind='foreach: linesSorted'> 
    <tr> 
     <td> 
      <span data-bind="text: lineGroupId"></span> 
     </td> 
     <td> 
      <span data-bind="text: lineType"></span> 
     </td> 
    </tr> 
</tbody> 
</table> 
function myViewModel() { 
    var self = this; 

    self.selectedLineType = ko.observable(2); 
    self.selectedGroupId = ko.observable(2); 

    self.lines = ko.observableArray([ 
     {lineType: 1, lineGroupId: 1}, 
     {lineType: 1, lineGroupId: 2}, 
     {lineType: 1, lineGroupId: 3}, 

     /*{lineType: 2, lineGroupId: 1}, 
     {lineType: 3, lineGroupId: 1}, 
     {lineType: 2, lineGroupId: 1}, 
     {lineType: 2, lineGroupId: 2}, 
     {lineType: 3, lineGroupId: 2}, 
     {lineType: 2, lineGroupId: 1},*/ 
    ]); 

    self.linesSorted = ko.pureComputed(function() { 
     return self.lines().sort(function (a, b) { 
      return a.lineType == b.lineType ? 
      0 : 
      (a.lineType < b.lineType ? -1 : 1); 
     }).sort(function (a, b) { 
      return a.lineGroupId == b.lineGroupId ? 
      0 : 
      (a.lineGroupId < b.lineGroupId ? -1 : 1); 
     }) 
    });  

    self.lineTypes = ko.observableArray([ 
     {value: 2, text: "2"}, 
     {value: 3, text: "3"} 
    ]); 

    self.lineGroupIds = ko.observableArray([ 
     {value: 1, text: "1"}, 
     {value: 2, text: "2"}, 
     {value: 3, text: "3"} 
    ]); 

    self.addLine = function() { 
     self.lines.push({ 
      lineType: self.selectedLineType(), 
      lineGroupId: self.selectedGroupId() 
     }); 
    }; 
} 

ko.applyBindings(new myViewModel()); 

他們應該通過LineGroupIdLineType進行排序,然後。對於每個LineGroupId,應該只有一個LineType 1.這是父項。我已經爲綁定到表的行添加了多重排序。它工作正常,直到行數超過10:那麼你會得到lineType爲2或3以上的lineType。任何有關這裏發生的事情的幫助將不勝感激。

回答

1

聽起來像他們正在文本排序,而不是數字。使用數字比較功能(參見參數示例here)。另外,按兩個字段排序,不要排序兩次,在同一個比較函數中進行兩個比較。這應該讓你排序(對不起):

function compareNumeric (a, b){return a-b} 

self.linesSorted = ko.pureComputed(function() { 
    return self.lines().sort(function (a, b) { 
     return compareNumeric(a.lineType, b.lineType) || compareNumeric(a.lineGroupId, b.lineGroupId); 
    }) 
}); 
1

你排序不是你想要的。

  • 你似乎想什麼:由直列型第一排序,然後通過線路組ID。
  • 你實際上在做什麼:通過線路類型排序,然後排序線路組ID結果再次

這是你的排序功能的更新版本:

self.linesSorted = ko.pureComputed(function() { 
    return self.lines().sort(function (a, b) { 
     if (a.lineGroupId > b.lineGroupId) { return 1; } 
     if (a.lineGroupId < b.lineGroupId) { return -1; } 
     if (a.lineType > b.lineType) { return 1; } 
     if (a.lineType < b.lineType) { return -1; } 
     return 0; 
    }) 
}); 

的演示中看到this jsfiddle

PS。我建議爲這種邏輯編寫單元測試。在CodeReview.SE上查看例如my somewhat related question about elegant "ThenBy" sorting in JavaScript

+0

謝謝。這工作完美。我一直在尋找關於如何做幾天的例子,但一無所獲。 –

相關問題