2016-02-05 46 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. teams()[4]找到points当你错过了第四的位置,使您的应用程序崩溃里面arrayForEach确保网上张贴问题 ;-)

  2. 你比较观测,不是他们的值之前检查错误控制台。您需要调用left.pointsright.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/),除非你切换'<'左右(不过一般我会建议不返回真/假从比较功能在所有情况下,只是一个数字;更好的返回例如'right.rank() - left.rank()')。 – Jeroen

+1

哦,是啊,我没有检查过这个比较,那个会提供升序:D已经提供了一个编辑。 – Adrian