2016-02-05 3 views
0

Я пытаюсь сортировать очки команд в порядке убывания, и я не понимаю, почему мой сорт не работает?Сортировка очков в порядке убывания в knockoutjs

https://jsfiddle.net/cjm2o08n/4/

<!-- ko foreach: teams --> 
<span data-bind="text: name"></span> <span data-bind="text: points"></span> 
<br/> 
<!-- /ko --> 




function Point(label, value) { 
    var self = this; 
    self.label = ko.observable(label); 
    self.value = ko.observable(value); 
} 

function Team(name) { 
    var self = this; 
    self.name = ko.observable(name); 
    self.rank = ko.observable(0); 
    self.points = ko.observable(0); 
} 

function AppViewModel() { 
    var self = this; 
    self.teams = ko.observableArray([ 
    new Team('red'), 
    new Team('blue'), 
    new Team('yellow'), 
    new Team('green'), 
    ]); 
    self.points = ko.observableArray([ 
    new Point('1st', 20), 
    new Point('2nd', 10), 
    new Point('3rd', 5) 
    ]); 

    self.tester = function() { 
    ko.utils.arrayForEach(self.teams(), function(team) { 
     //get team ranking and then find it in points 
     team.points(
     self.points()[team.rank() - 1].value() 
    ) 
    }); 
    //sort by highest points 
    self.teams(
     self.teams().sort(function(left, right) { 
     return left.points == right.points ? 0 : (left.points < right.points ? 1 : -1) 
     }) 
    ); 
    }; 
} 

var vm = new AppViewModel(); 
ko.applyBindings(vm); 

vm.teams()[0].rank(2); 
vm.teams()[1].rank(1); 
vm.teams()[2].rank(3); 
vm.teams()[3].rank(4); 

vm.tester(); 

ответ

1

Три вещи:

  1. Вы пропускаете четвертое место, что делает ваше приложение аварии внутри arrayForEach при нахождении points для teams()[4]. Обязательно проверьте консоль на наличие ошибок, прежде чем отправлять вопросы онлайн ;-)

  2. Вы сравнения наблюдаемых, а не их значения. Вам необходимо вызвать left.points и right.points, чтобы получить их значение.

  3. У observableArray есть функция sort, которая будет сортировать базовый массив;

Короче говоря, вам нужно изменить ваш points к этому:

self.points = ko.observableArray([ 
    new Point('1st', 20), 
    new Point('2nd', 10), 
    new Point('3rd', 5), 
    new Point('4th', 0) 
]); 

И ваш tester к этому:

self.tester = function() { 
    ko.utils.arrayForEach(self.teams(), function(team) { 
    //get team ranking and then find it in points 
    team.points(
     self.points()[team.rank() - 1].value() 
    ) 
    }); 
    //sort by highest points 
    self.teams.sort(function(left, right) { 
    return left.points() == right.points() ? 0 : (left.points() < right.points() ? 1 : -1) 
    }); 
}; 

Кстати, вы можете упростить вид даже это:

self.teams.sort(function(left, right) { 
    return right.points() - left.points(); 
    }); 

И things will work as intended.

2

Сортировка не работает для этих 2 ошибок.

первого этот код:

self.points()[team.rank() - 1].value() 

точки наблюдаемый массив содержит только 3 значения в то время как команду ранг может иметь значение 4, так self.points()[3].value() произведет ошибку.

Исправление будет заключаться в добавлении другого значения в массив точек, например: new Point('4th', 0), или вы можете найти другой способ, как захват, если индекс за пределами границ.

второй эта часть (сортировка):

return left.points == right.points ? 0 : (left.points < right.points ? 1 : -1) 

Помните, что точки является наблюдаемой, так что вы должны назвать его как функцию

return left.points() == right.points() ? 0 : (left.points() < right.points() ? 1 : -1) 

или вы даже можете сортировать его с помощью обеспеченное звание

return left.rank() - right.rank() 

Я здесь официантом, который вы предоставили. https://jsfiddle.net/56jgehjw/

+1

Ваше последнее предложение [не будет работать] (https://jsfiddle.net/54v4y4d1/), если вы не переключите '<' вокруг (хотя в целом я бы рекомендовал не возвращать true/false из функции сравнения на самом деле, но вместо этого вместо этого лучше вернуться, например, 'right.rank() - left.rank()'). – Jeroen

+1

О, да, я не проверил это сравнение, это обеспечит восходящий порядок: D предоставил редактирование уже. – Adrian

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