【问题标题】:Mapping JSON with knockout fails to populate type defined object properties使用敲除映射 JSON 无法填充类型定义的对象属性
【发布时间】:2013-07-12 10:12:23
【问题描述】:

我正在尝试使用 knockout.mapping 插件映射 JSON 数据,但是 heirarcical 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>

【问题讨论】:

  • 您能否发布 jsfiddle 示例?只需复制您的 json 数据并将其作为静态数据进行测试
  • 抱歉,应该一开始就这样做。幸运的是,@nevesv 在下面的答案中发布了一个小提琴修复。

标签: javascript knockout.js knockout-2.0 knockout-mapping-plugin


【解决方案1】:

因为您的 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,无需括号
  • 它适用于RootTarget 值为nullundified 的情况,因此它会隐藏输入,而您的原始解决方案RootTarget().ID 会引发空引用异常。

【讨论】:

  • 我真是个白痴,哈哈,我知道这很简单,但就是看不到明显的东西,谢谢先生 :)
【解决方案2】:

您需要在 roottarget 映射上加上括号,因为您需要先评估 observable,然后才能获得它的属性。

<p>RootTarget.ID: <input data-bind="value: RootTarget().ID" /></p>

另外,RootTarget 实际上不需要是一个可观察对象,只有它的属性才需要,所以如果你删除下面的行,它会自动创建为一个普通对象,并且你的绑定将照原样工作。

this.RootTarget = ko.observable;

【讨论】:

  • 它是从这个问题的 TypeScript 类定义转换而来的,但我想同样的规则也适用于那里,好提示!谢谢你:)
猜你喜欢
  • 1970-01-01
  • 2014-01-21
  • 1970-01-01
  • 2011-11-21
  • 2013-10-08
  • 2012-07-20
  • 1970-01-01
  • 2015-12-07
  • 2021-09-24
相关资源
最近更新 更多