I'd suggest keeping an internal "current track" number that you increment or decrement and base a computed on that.
function PlayerViewModel() {
var self = this,
currentTrackNo = ko.observable(0);
// data
self.tracks = ko.observableArray();
// computeds
self.currentTrack = ko.computed(function () {
return self.tracks()[currentTrackNo()];
});
self.hasTrack = function (track) {
return !!self.currentTrack();
};
self.hasNextTrack = ko.computed(function () {
return currentTrackNo() < self.tracks().length - 1;
});
self.hasPrevTrack = ko.computed(function () {
return currentTrackNo() > 0;
});
// API
self.setNextTrack = function () {
if (self.hasNextTrack()) {
currentTrackNo(currentTrackNo() + 1);
}
};
self.setPrevTrack = function () {
if (self.hasPrevTrack()) {
currentTrackNo(currentTrackNo() - 1);
}
};
self.setTrack = function (track) {
var trackNo = ko.utils.arrayIndexOf(self.tracks(), track);
currentTrackNo(trackNo);
};
// init
$.getJSON('...', {limit: 200}); etc;
}
Bind your "current track" view component to the currentTrack
observable. Make sure that you use hasTrack
in some way (as currentTrack
might be undefined).
Alternative implementation, avoiding the maintenance of a separate track number:
function PlayerViewModel() {
var self = this;
// data
self.tracks = ko.observableArray();
self.currentTrack = ko.observable();
// computeds
self.currentTrackNo = ko.computed(function () {
var currentTrack = self.currentTrack();
return ko.utils.arrayIndexOf(self.tracks(), currentTrack);
});
self.hasTrack = function (track) {
return !!self.currentTrack();
};
self.hasNextTrack = ko.computed(function () {
return self.currentTrackNo() < self.tracks().length - 1;
});
self.hasPrevTrack = ko.computed(function () {
return self.currentTrackNo() > 0;
});
// API
self.setNextTrack = function () {
if (self.hasNextTrack()) {
self.currentTrack(self.tracks()[self.currentTrackNo() + 1]);
}
};
self.setPrevTrack = function () {
if (self.hasPrevTrack()) {
self.currentTrack(self.tracks()[self.currentTrackNo() - 1]);
}
};
self.setTrack = function (track) {
// make sure that track is actually in self.tracks here
self.currentTrack(track);
};
// init
$.getJSON('...', {limit: 200}); etc;
}