https://stackoverflow.com/questions/47158758/knockoutjs-how-to-properly-bind-third-level-mapping
by jlspake
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/js/select2.min.js"></script>
<span data-bind="text: Title"></span>
<br/>
<span data-bind="text: LogoPath"></span>
<br/>
<span data-bind="text: StartDate"></span>
<br/>
<span data-bind="text: EndDate"></span>
<br/>
<div data-bind="foreach: ReservationOptions">
<div style="border: 1px dashed blue;">
<span data-bind="text: Title"></span>
<br/>
<span data-bind="text: Info"></span>
<br/>
<span data-bind="text: TypeDescription"></span>
<br/>
<div data-bind="foreach: ReservationOptionValues">
<div style="border: 1px dashed red;">
<span data-bind="text: ValueTitle"></span>
</div>
</div>
</div>
</div>
CSS
div {
min-height: 100px;
padding: 4px;
}
JavaScript
var data = {
"Id": 1017,
"Title": "title1",
"LogoPath": "logo1",
"StartDate": "06/11/2017",
"EndDate": "06/11/2017",
"StartTime": "00:00",
"EndTime": "00:10",
"TimeSpan": 1,
"MinPersons": 2,
"MaxPersons": 3,
"CompanyId": 1,
"ReservationOptions": [{
"Id": 1011,
"Title": "desc1",
"Info": "info1",
"TypeId": 1,
"TypeDescription": "Radio Button",
"ReservationOptionValues": [{
"Id": 1034,
"ValueTitle": "a"
}, {
"Id": 1035,
"ValueTitle": "b"
}, {
"Id": 1036,
"ValueTitle": "c"
}],
"NewValues": null
}]
};
ReservationViewModel = function(data) {
var self = this;
ko.mapping.fromJS(data, reservationOptionsMapping, self);
}
// 2nd level constructor
ReservationOptionsViewModel = function(data) {
var self = this;
ko.mapping.fromJS(data, reservationOptionValuesMapping, self);
}
//3nd level constructor
ReservationOptionsValuesViewModel = function(data) {
var self = this;
debugger
ko.mapping.fromJS(data, null, self);
}
var reservationOptionsMapping = {
'ReservationOptions': {
key: function(reservationOption) {
return ko.utils.unwrapObservable(reservationOption.Id);
},
create: function(options) {
return new ReservationOptionsViewModel(options.data,
reservationOptionValuesMapping);
}
}
}
var reservationOptionValuesMapping = {
'ReservationOptionValues': {
key: function(reservationOptionValues) {
return
ko.utils.unwrapObservable(reservationOptionValues.Id);
},
create: function(options) {
return new ReservationOptionsValuesViewModel(options.data);
}
}
}
var formControlsModel = new ReservationViewModel(data);
ko.applyBindings(formControlsModel);