Reputation: 1
I'm new to Knockout. Basically I need to get an array of items (pairs of price and quantity) from controller and then display it on my view. But before i display it, I want to use knockout to do some computation (calculate the subtotal) in the viewmodel, then pass the new array to the view. I know I can bind the original array to my view. But how can i pass this array to my viewmodel?
Upvotes: 0
Views: 1424
Reputation: 13478
You would not pass from a view to a viewmodel, it's the other way around. Controller passes data to a viewmodel, which is bound to a view. I digress.
There are several different techniques but a common one is to map the data into observable values. Knockout has a helper method arrayMap
which will help convert items in the array into observables. An example below:
var Item = function(data) {
var self = this;
self.Name = ko.observable(data.Name);
self.Price = ko.observable(data.Price);
self.Qty = ko.observable(data.Qty);
self.Total = ko.pureComputed(function() { return self.Price() * self.Qty();});
}
var viewModel = function() {
var self =this;
// list of items
self.Data = ko.observableArray([]);
// simulate ajax call to fetch data
self.Load = function() {
var data = [
{ Name: "A", Price: 12.34, Qty: 1},
{ Name: "B", Price: 23.45, Qty: 2 },
{ Name: "C", Price: 1234.56, Qty: 3 }
];
var mappedData = ko.utils.arrayMap(data, function(item) {
return new Item(item);
});
this.Data(mappedData);
}
}
var vm = new viewModel();
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul data-bind="foreach: Data">
<li>
Name: <span data-bind="text: Name"></span>
Quantity: <input type="text" data-bind="value: Qty" style="width: 100px;" />
Price: <input type="text" data-bind="value: Price" style="width: 100px;" />
Total: <span data-bind="text: Total"></span>
</li>
</ul>
<p>Click the button to simulate a load from API
<button data-bind="click: Load">Load</button></p>
Upvotes: 2