2016-02-05 48 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