In this jsfiddle I have a simple example of what I want to do working. It's all working just fine. But it seems like there has to be a better way to create these arrays with some loops or something. I've been trying all day and haven't succeeded. Can someone tell me if
Here's the code from the fiddle.
View:
<table>
<tbody>
<tr>
<td></td>
<!-- ko foreach: topvals -->
<td >
<input type="text" data-bind="value: val"/>
</td>
<!-- /ko -->
</tr>
<tr>
<td><input type="text" data-bind="value:sidevals()[0].val"/></td>
<!-- ko foreach: intersections()[0] -->
<td><span data-bind="text: val"></span></td>
<!-- /ko -->
</tr>
<tr>
<td ><input type="text" data-bind="value:sidevals()[1].val"/></td>
<!-- ko foreach: intersections()[1] -->
<td><span data-bind="text: val"></span></td>
<!-- /ko -->
</tr>
</tbody>
</table>
Viewmodel:
function ViewModel() {
this.topvals = ko.observableArray([
{ val: ko.observable(6) },
{ val: ko.observable(1) },
{ val: ko.observable(1) },
{ val: ko.observable(1) }
]);
this.sidevals = ko.observableArray([
{ val: ko.observable(1) },
{ val: ko.observable(1) },
{ val: ko.observable(1) }
]);
this.intersections = ko.observableArray([
[
{ val: ko.computed(function () { return this.topvals()[0].val() * this.sidevals()[0].val(); }, this) },
{ val: ko.computed(function () { return this.topvals()[1].val() * this.sidevals()[0].val(); }, this) },
{ val: ko.computed(function () { return this.topvals()[2].val() * this.sidevals()[0].val(); }, this) },
{ val: ko.computed(function () { return this.topvals()[3].val() * this.sidevals()[0].val(); }, this) }
],
[
{ val: ko.computed(function () { return this.topvals()[0].val() * this.sidevals()[1].val(); }, this) },
{ val: ko.computed(function () { return this.topvals()[1].val() * this.sidevals()[1].val(); }, this) },
{ val: ko.computed(function () { return this.topvals()[2].val() * this.sidevals()[1].val(); }, this) },
{ val: ko.computed(function () { return this.topvals()[3].val() * this.sidevals()[1].val(); }, this) }
]
]);
}
ko.applyBindings(new ViewModel());
topvals
and sidevals
arrays you can use ko.mapping.fromJS.intersections
you can return an "array of arrays" using the ko.utils.arrayMap function.Here is the final code (and a jsfiddle):
function ViewModel() {
var self = this;
var calculateIntersection = function(topval, sideval) {
return topval * sideval;
};
var topvals = [{ val: 1 }, { val: 2 }, { val: 3 }];
var sidevals = [{ val: 1 }, { val: 2 }, { val: 3 }];
self.topvals = ko.mapping.fromJS(topvals);
self.sidevals = ko.mapping.fromJS(sidevals);
self.intersections = ko.computed(function() {
return ko.utils.arrayMap(self.sidevals(), function(sideval) {
return ko.utils.arrayMap(self.topvals(), function(topval) {
return calculateIntersection(topval.val(), sideval.val());
});
});
});
}
ko.applyBindings(new ViewModel());
And here is the view:
<table>
<tbody>
<tr>
<td></td>
<!-- ko foreach: topvals -->
<td >
<input type="text" data-bind="value: val"/>
</td>
<!-- /ko -->
</tr>
<!-- ko foreach: sidevals -->
<tr>
<td><input type="text" data-bind="value: val"/></td>
<!-- ko foreach: $root.intersections()[$index()] -->
<td><span data-bind="text: $data"></span></td>
<!-- /ko -->
</tr>
<!-- /ko -->
</tbody>
</table>
This simple view model already does it:
function ViewModel(vals1, vals2) {
this.topvals = ko.observableArray(mapToObservables(vals1));
this.sidevals = ko.observableArray(mapToObservables(vals2));
this.calc = function (val1, val2) {
return ko.unwrap(val1) * ko.unwrap(val2);
};
}
ko.applyBindings(new ViewModel([6, 5, 4, 3], [1, 2, 3]));
where mapToObservables
stands for either the mapping plugin or a function like this one:
function mapToObservables(vals) {
return ko.utils.arrayMap(vals, function (val) {
return { val: ko.observable(val) };
});
};
and this view
<table>
<tbody>
<tr>
<td></td>
<!-- ko foreach: topvals -->
<td><input type="text" data-bind="value: val"/></td>
<!-- /ko -->
</tr>
<!-- ko foreach: sidevals -->
<tr>
<td><input type="text" data-bind="value: val"/></td>
<!-- ko foreach: $root.topvals -->
<td><span data-bind="text: $root.calc(val, $parent.val)"></span></td>
<!-- /ko -->
</tr>
<!-- /ko -->
</tbody>
</table>
See: http://jsfiddle.net/dt9kL/
A variant would be to use a separate sub-model for the values: http://jsfiddle.net/dt9kL/1/. For encapsulating a single value this is overkill, but it might be useful for more complex structures.
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