事前に感謝することから始めましょう:)
OK、ノックアウト マッピング プラグインを使用して、一致する JSON データから階層型の TypeScript/KnockoutJS 型付きクラスをロード/マップしようとしています。階層は N 次まで可能です。
JSONデータから最上位クラスをマップ/ロードするには、次のことができることを知っています。
var qry = ko.mapping.fromJS(jsData, {}, new Query());
ただし、複雑なN次の階層JSONデータを一連のTypeScript/KnockoutJSクラスにマップ/ロードし、親子関係を構築する方法はわかりません。
私は数え切れないほどの記事を読みましたが、単純な親子の例を超えた階層関係に関しては、どれも不十分であり、knockout.mapping プラグインを使用しても見つかりません。
これは、マップ/ロードしたいTypeScriptクラスの定義を切り詰めたものです。私は c++/c# 開発者なので、この性質の JavaScript は私にとってまったく新しいものです。
TypeScript オブジェクト
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 は次のようになります。
{
"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": []
}
]
}
}
}