I am trying to calculate sum of 'price' field of an 'observableArray'. I have the following code so far:
(function(){
function objFeatures(name,price) {
return {
name: ko.observable(name),
price: ko.observable(price),
removeFeatures: function () {
appViewModel.features.remove(this);
}
}
}
var appViewModel = {
features: ko.observableArray([
new objFeatures("Feature1", 20),
new objFeatures("Feature2", 20)
]),
grandTotal: ko.computed(function () {
var total = 0;
ko.utils.arrayForEach(this.features(), function () {
total += this.price();
})
return total;
})
};
ko.applyBindings(appViewModel);
}());
When I try to run this, i get an "Error: this.features is not a function" in the firebug console.
What am i doing wrong?
If you want to detect and respond to changes of a collection of things, use an observableArray . This is useful in many scenarios where you're displaying or editing multiple values and need repeated sections of UI to appear and disappear as items are added and removed.
You should look at defining the object structure for each element of your array and then add elements of that type to your observable array. Once this is done, you will be able to do something like item. productQuantity(20) and the UI will update itself immediately. EDIT Added the function provided by the OP :).
Description. The KnockoutJS Observable sort() method sorts all items in the array. By default, items are sorted in an ascending order. For sorting an array in a descending order, use reverse() method on sorted array.
Computed observables are evaluated immediately during creation. In your case, appViewModel
has not been created yet and this
will not represent the appViewModel
.
There are many ways to ensure that this
is correct in this case. Here are two:
Create it outside of your initial object literal:
var appViewModel = {
features: ko.observableArray([
new objFeatures("Feature1", 20),
new objFeatures("Feature2", 20)
])
};
appViewModel.grandTotal = ko.computed(function() {
var total = 0;
ko.utils.arrayForEach(this.features(), function(feature) {
total += feature.price();
});
return total;
}, appViewModel);
Create your view model in a function:
var AppViewModel = function() {
this.features = ko.observableArray([
new objFeatures("Feature1", 20),
new objFeatures("Feature2", 20)
]);
this.grandTotal = ko.computed(function() {
var total = 0;
ko.utils.arrayForEach(this.features(), function(feature) {
total += feature.price();
});
return total;
}, this);
};
ko.applyBindings(new AppViewModel());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With