Reputation: 5355
I am having WebApi that returns Countries with Companies.
The object returned is in the following format:
[{"$id":"1", "Name":"Denmark", "Currency":"DKK", "Companies":[],",
{"$id":"2","Name":"Belgium","Currency":"EUR","Companies":[],
{"$id":"3","Name":"Austria","Currency":"EUR","Companies":[{"$id":"4","Name":"Belgium Company 1"},...]
So, there is a list of Countries and each Country has a list of companies.
How to map this structure to knockout?
I have knockout model viewModel
with different properties:
this.objectId = ko.observable();
this.Country = ko.observable(); // this is selected country for given object
this.Countries = ko.observableArray();
this.Company = ko.observable(); //this is selected company for given object
this.Companies = ko.observableArray();
this.ContactName = ko.observable();
...
When page loads I am populating viewModel and binding UI. During this I also call webApi and get countries+companies in the format as described above.
function _getCountries() {
return $.ajax({
url: "/api/portfolio/GetCountries",
contentType: "application/json",
dataType: "json",
type: "GET"
});
}
I am calling _getCountries during model initialization that loads model data like objectId, ContactName etc. When this init is done, I am calling _getCountries:
_getCountries().done(function (dataJson) {
ko.mapping.fromJS(dataJson, {}, ParentModel.ChildModelInst.Countries);
}).fail(function () {
alert("fail");
});
this.Countries
and this.Companies
should be used to populate dropdowns, for example:
<select data-bind="options: Countries, value: Country"></select>
The question/problem: 1) Above doens't work, because Countries consists of objects and it shows me dropdown with "objects"
2) I need somehow define Countries and Companies so that those are related. If I change countries then appropriate companies are loaded into dropdown. (so this.Companies should be loaded accordingly to this.Country that is selected item from this.Countries).
Upvotes: 1
Views: 90
Reputation: 3591
You need to created computed observable to get company names. So i suggest following.
Html for Country and Company dropdown
<select data-bind="options: Countries, value: Country, optionsText: 'Name'"></select>
<select data-bind="options: filteredCompanies, optionsText: 'Name'"></select>
On subscribe event of "Country" created computed function to return list of Companies for the selected Countries
this.Country.subscribe(function(value) {
self.filteredCompanies = ko.computed(function() {
if (value.Companies != undefined){
return value.Companies;
}
});
});
Upvotes: 1