JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://raw.github.com/SteveSanderson/knockout.mapping/23fb458cac7f85ce075f37b969f083f355969cfa/build/output/knockout.mapping-latest.js"></script>
<script type="text/html" id="nestedTemplate">
<!-- ko if: type == 'simple' -->
<div class="name" data-bind="text: value, attr: {title: key}"></div>
<!-- /ko -->
<!-- ko if: type == 'array' -->
<div class="container" data-bind="
template: {
name: 'nestedTemplate',
foreach: value
}
"></div>
<!-- /ko -->
</script>
<div class="container" data-bind="
template: {
name: 'nestedTemplate',
foreach: master
}
"></div>
CSS
div.container div.container {
margin-left: 10px;
}
JavaScript
var ListModel = function(jsonData) {
var self = this;
self.master = ko.observableArray([]);
function nestedMapping(data, level) {
var key, value, type;
for (key in data) {
if (data.hasOwnProperty(key)) {
if (data[key] instanceof Object) {
type = "array";
value = ko.observableArray( [] );
nestedMapping(data[key], value());
} else {
type = "simple";
value = ko.observable(data[key]);
}
level.push({key: key, type: type, value: value});
}
}
}
nestedMapping(jsonData, self.master());
}
var jsonData = {
"Level 1a": "Hi",
"Level 1b": {
"Level 2a": "Hello",
"Level 2b": {
"Level 3": "Bye"
}
}
};
var listModel = new ListModel(jsonData);
ko.applyBindings(listModel);