I for the life of me can't get this array to sort appropriately. I know the sort function works but the timing of some sort is off. Can't seem to figure it out.
UI
<!-- ko foreach: Times.sort(function (l, r) { app.utils.orderTime(l.Time(), r.Time()); }) -->
Javascript
function Day(date, updated) {
var self = this;
self.Times = ko.observableArray([]);
var times = ko.utils.arrayMap(date.Times, function (item) {
return new Time(item, updated);
});
self.Times.push.apply(self.Times, times);
}
Sort Function
app.utils.orderTime = function(l, r) { // l = "9:00 AM", r = "11:00 PM"
var leftFormatted = new Date('1/1/2012 ' + l); // Sun Jan 01 2012 09:00:00 GMT-0700
var rightFormatted = new Date('1/1/2012 ' + r); // Sun Jan 01 2012 23:00:00 GMT-0700
return leftFormatted.compareTo(rightFormatted); // -1
};
UPDATE:
I went ahead and added a computed called TimeSorted and sorts great, but I cant push anything into the time array and have it updated unless I have self.Times().sort(
... instead but then the order isnt kept.
self.TimesSorted = ko.computed(function() {
return self.Times.sort(function (l, r) { app.utils.orderTime(l.Time(), r.Time()); });
});
<!-- ko foreach: TimesSorted -->
The sort
method modifies the array it acts on and thus changes the original array. The fact that it also returns that array is what confuses a lot of people. A binding like this shouldn't be modifying the array; it should be working with a copy of the array:
<!-- ko foreach: Times.slice(0).sort(...) -->
The observable array sort
method changes the array (just like push
, splice
, etc.) and notifies subscribers of the change. It doesn't create a dependency on the array within a binding or computed observable. The slice
method, on the other hand, does create a dependency.
If you really do want to sort the original array, this really shouldn't be done in a binding. I suggest you use an extender such as this:
ko.extenders.sorted = function (obs, sortFunction) {
obs.sort(sortFunction);
obs.subscribe(function (array) {
array.sort(sortFunction);
});
}
...
self.Times = ko.observableArray([]).extend({ sorted: function (l, r) { return app.utils.orderTime(l.Time(), r.Time()); } });
Example: http://jsfiddle.net/mbest/f3SX2/
Geez I feel a dumb. I wasn't returning anything in the sort function of the array, just called a method. This fixed it and I add to add ()
to the observable array.
<!-- ko foreach: Times().sort(function (l, r) { return app.utils.orderTime(l.Time(), r.Time()); }) -->
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.