Please, look at my text. I try to use observableArray of knockoutjs and foreach to compute data of array. Example 1 works fine: total sum computed if you change data in the fields. But Example 2 is not working.
<html>
<head>
<title></title>
<script type='text/javascript' src='/js/jquery-1.8.2.min.js'></script>
<script type='text/javascript' src='/js/knockout-2.1.0.debug.js'></script>
</head>
<body>
<p>Example 1</p>
<div>
<p>
<input data-bind="value: fnum1" />
<input data-bind="value: fnum2" />
<span data-bind="text: ftotsum"></span>
</p>
</div>
<p>Example 2</p>
<div>
<p>
<!-- ko foreach: fields -->
<input data-bind="value: $data" />
<!-- /ko -->
<span data-bind="text: ltotsum"></span>
</p>
</div>
</body>
<script>
function vm(){
//Calc Example 1
var self = this;
self.fnum1 = ko.observable(1);
self.fnum2 = ko.observable(2);
self.ftotsum = ko.computed(function(){
return parseFloat(self.fnum1()) + parseFloat(self.fnum2());
});
//Calc Example 2
self.fields = ko.observableArray([1, 2]);
self.ltotsum = ko.computed(function(){
var total = 0;
ko.utils.arrayForEach(self.fields(), function(item) {
total += parseFloat(item);
})
return total;
});
};
ko.applyBindings(new vm());
</script>
</html>
EDIT: Got fiddle working, Raffaele is correct in saying you need to wrap the observable inside an object, but you can do it within the array creation itself and I like to use the ko.utils to unwrap my observables, it does the same thing for observables but it won't crash if there is a non-observable passed to it. See fiddle for full example.
An observableArray doesn't make the values passed observable, this is a common mistake. An observableArray just observes the modifications to the array and not the values. If you want to have your values inside your array be observable you have to make them so.
Should work with the example above now.
The documentation says:
Your second example doesn't work because the value of the input fields is not bound to the values in the array. That values in the array are used only once, in the
foreach
binding, but when you type in the input boxes, nothing triggers KO.Here is a working fiddle with a solution implemented. I used a helper
ObsNumber
and the following markup