我正在尝试使用knockout.mapping插件映射JSON数据,但是继承的JSON数据无法正确填充我的对象属性,顶层加载了很好的数据,但没有加载子"RootTarget"数据?
我做错了什么?
淘汰Javascript
var Query = function(json)
{
this.ID = ko.observable(0);
this.Name = ko.observable();
this.RootTargetID = ko.observable();
this.RootTarget = ko.observable();
var mapping = {
'RootTarget': {
create: function (args) {
return new QueryTarget(args.data, null);
}
}
};
ko.mapping.fromJS(json, mapping, this);
}
var QueryTarget = function(json, parent)
{
this.ID = ko.observable(0);
this.Name = ko.observable();
this.ParentID = ko.observable(0);
this.Parent = ko.observable(parent);
this.FilterID = ko.observable(0);
var mapping = {
'ignore': ["Parent"]
};
ko.mapping.fromJS(json, mapping, this);
}
var QueryModuleViewModel = function()
{
var json = {
"ID": 2,
"Name": "Northwind 2",
"RootTargetID": 2,
"RootTarget": {
"ID": 2,
"Name": "Customers",
"ParentID": null,
"FilterID": 2,
"Parent": null
}
};
this.QueryObj = new Query(json);
}
window.onload = function () {
ko.applyBindings(new QueryModuleViewModel());
};
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>TypeScript Knockout Mapping Query Test</title>
<link rel="stylesheet" href="app.css" type="text/css" />
<script src="Scripts/jquery-2.0.2.js" type="text/javascript"></script>
<script src="Scripts/knockout-2.2.1.debug.js" type="text/javascript"></script>
<script src="Scripts/knockout.mapping-latest.debug.js" type="text/javascript"></script>
<script src="my_js_query_test.js"></script>
</head>
<body>
<h1>TypeScript Knockout Mapping Query Test</h1>
<div data-bind="with: QueryObj">
<span data-bind="blah: console.log($context)"></span>
<p>Query Name: <input data-bind="value: Name" /></p>
<hr />
<p>Quick test of RootTarget Values</p>
<p>RootTarget.ID: <input data-bind="value: RootTarget.ID" /></p>
<p>RootTarget.Name: <input data-bind="value: RootTarget.Name" /></p>
</div>
</body>
</html>
因为您的RootTarget
被声明为ko.observable
,这是一个函数,所以您需要使用空参数()
来调用它,以获取其值并访问存储的对象。
因此,您只需要更改绑定并添加缺少的()
:
<p>RootTarget.ID: <input data-bind="value: RootTarget().ID" /></p>
<p>RootTarget.Name: <input data-bind="value: RootTarget().Name" /></p>
演示JSFiddle。
或者你可以在这里使用with
绑定
<p>Quick test of RootTarget Values</p>
<!-- ko with: RootTarget -->
<p>RootTarget.ID: <input data-bind="value: ID" /></p>
<p>RootTarget.Name: <input data-bind="value: Name" /></p>
<!-- /ko -->
演示JSFiddle。
它有一些不错的优点:
- 你不必重复
RootTarget
with
会自动打开可观测值,这样您就可以只写with: RootTarget
,而不需要parens- 它适用于
RootTarget
值为null
或undified
的情况,因此它隐藏输入,而原始解决方案RootTarget().ID
将抛出空引用异常
您需要在roottarget映射上加括号,因为您需要在获取可观察对象的属性之前对其进行评估。
<p>RootTarget.ID: <input data-bind="value: RootTarget().ID" /></p>
或者,RootTarget实际上不需要是可观察的,只有它的属性才需要,所以如果你删除下面的行,它将自动创建为一个普通对象,你的绑定将按原样工作。
this.RootTarget = ko.observable;