I have an issue with updating an observableArray. I must be missing something here but what I have is this:
I have a list of values stored in my main viewmodel like this:
function AppViewModel() {
var self = this;
self.q1 = ko.observable().extend({ number: true });
self.q2 = ko.observable().extend({ number: true });
self.q3 = ko.observable().extend({ number: true });
self.q4 = ko.observable().extend({ number: true });
self.q5 = ko.observable().extend({ number: true });
.
.
.
I have a list of computed functions calculating Average values. I also have a separate viewmodel for creating a Chart using jqxWidgets. This is the code:
function ChartModel(scores) {
var self = this;
var cat;
self.scores = ko.observableArray(scores);
self.scores.push({ cat: "Re", score: vm.reAve() });
self.scores.push({ cat: "Da", score: vm.daAve() });
self.scores.push({ cat: "De", score: vm.deAve() });
self.scores.push({ cat: "Im", score: vm.imAve() });
self.scores.push({ cat: "Ps", score: vm.psAve() });
self.scores.push({ cat: "Overall", score: vm.reAve() });
//alert(self.scores()[0].score);
self.updateScores = function () {
var item = {};
item.cat = "Re";
item.score = vm.reAve();
self.scores.replace(self.scores()[0], item);
item.cat = "Da";
item.score = vm.daAve();
self.scores.replace(self.scores()[1], item);
item.cat = "De";
item.score = vm.deAve();
self.scores.replace(self.scores()[2], item);
item.cat = "Im";
item.score = vm.imAve();
self.scores.replace(self.scores()[3], item);
item.cat = "Ps";
item.score = vm.psAve();
self.scores.replace(self.scores()[4], item);
item.cat = "Overall";
item.score = vm.basAve();
self.scores.replace(self.scores()[5], item);
};
}
var vm = new AppViewModel();
var cm = new ChartModel(scores);
I apply the bindings at the end of my $(document).ready(...)
block. The issue is that the scores
never gets updated when the updateScores function is called:
<button id="btnLoad" data-bind="click: cm.updateScores">View Chart</button>
Desperately need help/advice. Thanks.
EDIT: Have created a fiddle but unfortunately nothing works here. The radio buttons are supposed to update their respective observables and then calculate Total and Average values. It works fine in my project but I can't seem to reproduce it accurately in jsfiddle. Have been stuck on this the past hour. Here is the fiddle:
What I'm struggling with in my project is that the observableArray values never get updated. Am sure I'm missing something but I don't know what...
EDIT 2 :
Ok, in my Questions model, I am trying to take the scores for 3 particular questions, store it in an observable array, and then calculate the maximum value that was chosen. I can't seem to get the UI to update to reflect the changes and console.log does not show me anything:
function CategoryModel(cat) {
var self = this;
self.name = cat.name;
self.itemsChosen = ko.observable();
self.catquestion = ko.utils.arrayMap(cat.qs, function (q) {
return new CatQuestionModel(q.label, q.number);
});
self.catTotalScore = ko.computed(function () {
var total = 0, numItems = 0;
ko.utils.arrayForEach(self.catquestion, function (question) {
// note that ~~ converts its operand to integer (or 0 if that fails)
total += ~ ~question.score() + ~~question.mdaScoreM();
if (!(isNaN(question.score()))) {
++numItems;
self.itemsChosen(numItems);
}
});
return total;
}, self);
self.catAvgScore = ko.computed(function () {
return parseFloat(self.catTotalScore() / (self.itemsChosen() || 1)).toFixed(2);
});
}
function CatQuestionModel(question, number) {
var self = this;
self.question = question;
self.number = number;
self.score = ko.observable();
self.mdaScore = ko.observable();
self.mdaVals = ko.observableArray([]);
if (self.number == "2" || self.number == "3" || self.number == "4")
self.mdaVals.push(ko.observable({ "number": self.number, "score": self.mdaScore() }));
self.mdaScoreM = ko.computed(function () {
var x = 0;
x = ko.utils.arrayFirst(self.mdaVals(), function (i) {
return i.score === Math.max.apply(null, ko.utils.arrayMap(self.mdaVals(), function (e) {
return e.score;
}));
});
return x;
}, self);
self.mdaVals.notifySubscribers(self.mdaVals());
}
mdaVals() is the array for holding all 3 values and mdaScore is supposed to be the max value obtained. Is there anything wrong with the above code?
If you want the value on the page to be updated when a value on an object inside the array changes you need to declare each value on the object as an observable.
self.mdaVals = ko.observableArray([]);
self.mdaVals.push({ number: ko.observable(1), score: ko.observable(20)});
self.mdaVals()[0].number(2);
self.mdaVals()[0].score(10);