2015-06-08 4 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()); 

Они должны быть отсортированы по LineGroupId, а затем LineType. Для каждого LineGroupId должен быть один и только один из LineType 1. Это родительский элемент. Я добавил несколько видов в строки, привязанные к таблице. Он работает нормально до тех пор, пока количество строк не переместится через 10: тогда вы получите lineType из 2 или 3 выше lineType 1. Любая помощь в том, что здесь происходит, будет очень признательна.

ответ

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

Вы сортировки не так, как вы хотите.

  • То, что вы, кажется, хотят: сортировать по линии типа первый, затем Line Id Group.
  • Что вы на самом деле делает: сортировать по линии типа, то сортировки результатов снова по линии Id Group.

Вот обновленная версия вашей сортировочной функции:

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. Я рекомендую писать модульные тесты для такого рода логики. См. Например, my somewhat related question about elegant "ThenBy" sorting in JavaScript на CodeReview.SE.

+0

Благодарю вас. Это сработало отлично. Я искал примеры того, как это делать в течение нескольких дней и ничего не нашел. –

Смежные вопросы