Reputation: 47
Learning KnockoutJS and hit a brick wall. Making a calculator for a game. A summarized version is below:
User inputs 'neededXp'. Array should recalculate 'need' everytime 'neededXp' is updated.
self.neededXp = ko.observable(0);
function calcItem(name, image, xp, level) {
this.name = name;
this.level = level;
this.xp = xp;
this.need = ko.computed(function() {
var req = self.neededXp()/this.xp;
return req;
});
}
self.calcContent = ko.observableArray([
]);
self.populateFishing = function() {
self.calcContent.push(calcItem('Shrimp','#',1,10));
self.calcContent.push(calcItem('Sardine','#',5,20));
self.calcContent.push(calcItem('Shark','#',110,76));
self.calcContent.push(calcItem('Sea Turtle','#',38,79));
self.calcContent.push(calcItem('Manta Ray','#',46,81));
}
At the moment, it calculates for the first time perfectly, and it appears that when 'neededXp' is updated, it recalculates all values with the correct 'neededXp', but the computed observable for each index in the array reads the 'xp' from the last member of the array.
To clarify, when I update 'neededXp', all members 'need' are recalculated with the 'xp' from the Manta Ray value, rather than their respective indexes.
Probably something really obvious, hope someone can direct me though.
EDIT: After re-reading my code, I think I can see why it's happening, but I don't know how to fix. I don't know how to maintain the 'xp' value in the array, if that makes sense.
EDIT2: http://jsfiddle.net/sTnY7/ jsfiddle with reduced size arrays for usability. Hit the fish button to populate the table, then change the "Goal Level" to 6 for easiest demonstration of the problem. This is where the problem happens - all the "# Required" take the XP value from the last member of the array and recalculate. If Goal Level is 6, it shows 102.2 - where "Shrimp" should be 511, for example.
Hope this makes sense.
Upvotes: 0
Views: 233
Reputation: 9049
Ok - so I created a fiddle myself
Had to make a couple of changes -
Scoping (as I suspected) - calcItem now looks like this:
function calcItem(name, image, xp, level) {
var self2 = this;
self2.name = name;
self2.level = level;
self2.xp = xp;
self2.need = ko.computed(function () {
var req = self.neededXp() / self2.xp;
return req;
});
Also, you missed the new
while creating calcItem
objects and pushing them to calcContent
.
I changed populateFishing
to look like
self.populateFishing = function () {
self.calcContent.push(new calcItem('Shrimp', '#', 1, 10));
self.calcContent.push(new calcItem('Sardine', '#', 5, 20));
self.calcContent.push(new calcItem('Shark', '#', 110, 76));
self.calcContent.push(new calcItem('Sea Turtle', '#', 38, 79));
self.calcContent.push(new calcItem('Manta Ray', '#', 46, 81));
}
You can see the bound data change on updating the neededXp in this fiddle.
Upvotes: 1