Let's start with thanks in advance :)
OK, so I'm trying to load / display hierarchical TypeScript / KnockoutJS typed classes from the corresponding JSON data using the knockout.mapping plugin, the hierarchy can be in the Nth degree.
I know that I can do the following to display / load the top level class from JSON data.
var qry = ko.mapping.fromJS(jsData, {}, new Query());
However, I cannot figure out how to map / load complex, Nth degree, hierarchical JSON data into a TypeScript / KnockoutJS class set and build parent / child relationships.
I read countless articles, but all of them are not suitable when it comes to hierarchical relationships outside of simple parent / child examples, and I cannot find them using the knockout.mapping plugin.
Here are my abbreviated TypeScript class definitions that I want to display / load. I am a C ++ / C # developer, so JavaScript of this type is very new to me.
TypeScript Objects
module ViewModel { export class QueryModuleViewModel { public QueryObj: KnockoutObservable<Query>; constructor() { this.QueryObj = ko.observable<Query>(); } public Initialize() { $.getJSON("/api/query/2", null, d => { var qry = ko.mapping.fromJS(d, {}, new Query()); this.QueryObj(qry); }); } } export class Query { public ID: KnockoutObservable<number>; public Name: KnockoutObservable<string>; public RootTargetID: KnockoutObservable<number>; public RootTarget: KnockoutObservable<QueryTarget>; constructor() { this.ID = ko.observable<number>(0); this.Name = ko.observable<string>(); this.RootTargetID = ko.observable<number>(); this.RootTarget = ko.observable<QueryTarget>(); } } export class QueryTarget { public ID: KnockoutObservable<number>; public Name: KnockoutObservable<string>; public ParentID: KnockoutObservable<number>; public Children: KnockoutObservableArray<QueryTarget>; public Parent: KnockoutObservable<QueryTarget>; public Selects: KnockoutObservableArray<QuerySelect>; public FilterID: KnockoutObservable<number>; public Filter: KnockoutObservable<FilterClause>; constructor() { this.ID = ko.observable<number>(0); this.Name = ko.observable<string>(); this.ParentID = ko.observable<number>(0); this.Children = ko.observableArray<QueryTarget>(); this.Parent = ko.observable<QueryTarget>(); this.Selects = ko.observableArray<QuerySelect>(); this.FilterID = ko.observable<number>(0); this.Filter = ko.observable<FilterClause>(); } } export class QuerySelect { public ID: KnockoutObservable<number>; public Name: KnockoutObservable<string>; public Aggregation: KnockoutObservable<string>; public TargetID: KnockoutObservable<number>; public Target: KnockoutObservable<QueryTarget>; constructor() { this.ID = ko.observable<number>(); this.Name = ko.observable<string>(); this.Aggregation = ko.observable<string>(); this.TargetID = ko.observable<number>(); this.Target = ko.observable<QueryTarget>(); } } export class FilterClause { public FilterClauseID: KnockoutObservable<number>; public Type: KnockoutObservable<string>; public Left: KnockoutObservable<string>; public Right: KnockoutObservable<string>; public ParentID: KnockoutObservable<number>; public Parent: KnockoutObservable<FilterClause>; public Children: KnockoutObservableArray<FilterClause>; public QueryTargets: KnockoutObservableArray<QueryTarget>; constructor() { this.FilterClauseID = ko.observable<number>(); this.Type = ko.observable<string>(); this.Left = ko.observable<string>(); this.Right = ko.observable<string>(); this.ParentID = ko.observable<number>(); this.Parent = ko.observable<FilterClause>(); this.Children = ko.observableArray<FilterClause>(); } } }
JSON will look something like this:
{ "ID": 2, "Name": "Northwind 2", "RootTargetID": 2, "RootTarget": { "ID": 2, "Name": "Customers", "ParentID": null, "FilterID": 2, "Queries": [], "Children": [], "Parent": null, "Selects": [ { "ID": 3, "Name": "CompanyName", "Aggregation": "None", "TargetID": 2, "Target": null }, { "ID": 4, "Name": "ContactName", "Aggregation": "None", "TargetID": 2, "Target": null } ], "Filter": { "FilterClauseID": 2, "Type": "AND", "Left": null, "Right": null, "ParentID": null, "QueryTargets": [], "Parent": null, "Children": [ { "FilterClauseID": 3, "Type": "NE", "Left": "Country", "Right": "Germany", "ParentID": 2, "QueryTargets": [], "Parent": null, "Children": [] }, { "FilterClauseID": 4, "Type": "NE", "Left": "Country", "Right": "Mexico", "ParentID": 2, "QueryTargets": [], "Parent": null, "Children": [] } ] } } }