Adding an Infinite Nested Hierarchy of Observable Objects Using Knockout from .NET Core / MVC

Sometimes you may come across a situation where your JSON is representing a hierarchy of objects, which you then would like to show on a page. One of the common ways to do that is nested div‘s but, of course, there are other ways to do that as well, such as blades, tabs, etc. The question in effect here is, how do you do it using Knockout library?

Let me start with an assumption that your object is returned from an API as JSON and it contains child items of the same type (unknown level of depth). A common scenario would be configuration settings where a configuration section may contain more configuration settings or a hierarchy of employees where each employee may have one or more subordinates:

[
	{
		id: 1,
		Name: 'John Smith',
		Subordinates: [
			{ id: 2, Name: 'Jane Smith', Subordinates: [] },
			{ id: 3, Name: 'Joe Seth', Subordinates: [] }
		]
	},
	{
		id: 4,
		Name: 'Bobby Kane',
		Subordinates: [{ 
				id: 5, Name: 'Samantha Hale' 
				Subordinates: [
					{ id: 6, Name: 'Mike Booth', Subordinates: [] }
				] 
			}
		]
	}
]

Now, the first thing I’d like to mention is that I assume you’re getting the whole array from an API call. You can certainly wrap that into a DOM, if o desired. So, let’s make life easier and use Knockout Mapping library to bind the whole thing:

	var rawJSON = @Html.Raw(JsonConvert.SerializeObject(Model.Employees));
	var jsonModel = JSON.stringify(rawJSON);
	var mvcModel = ko.mapping.fromJSON(jsonModel, {
            'Subordinates': {
                key: function(item) {
                    return ko.utils.unwrapObservable(item.id);
                }
            }
        });
        var viewModel = new ViewModel();
	var koModel = ko.mapping.fromJS(viewModel, mvcModel);
	ko.applyBindings(window.koModel);

First, we get the raw JSON from our .NET model and stringify it so we can pass it on as JSON to the ko.mapping to create the MVVC model. The ViewModel class is just a wrapper, you don’t need to have anything there:

function ViewModel() {
}


Then we get our ko model and the call to applyBindings() will bind the whole thing so it is now observable, every single property.
Now, on to the fun part. The way to implement a hierarchy is to define a template and reference itself from within the same template. You will still need the top element. Let's start with the template itself:


First, we simply list the name but then we got a foreach on a table (or any element you'd like). Since we are specifying a template for the foreach in the binding, we are gaining the recursive rendering.

As always, I hope this helps someone to get a kick start! Fell free to comment, ask questions, etc!

This entry was posted in Knockout and tagged , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *