Mapping JSON with knockout fails to populate type defined object properties

北城余情 提交于 2019-12-13 18:34:09

问题


I'm trying to map JSON data using the knockout.mapping plugin, however the heirarcical JSON data fails to populate my object properties correctly, the top level loads fine but not the child 'RootTarget' data?

What am I doing wrong?

Knockout 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>

回答1:


Because your RootTarget is declared as an ko.observable which is a function so you need to call it with empty args () to get its value and access the stored object.

So you just need to change your bindings and add the missing ():

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

Demo JSFiddle.

Or you can use here the with binding

<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 -->

Demo JSFiddle.

It has some nice advantages:

  • you don't have to repeat RootTarget
  • the with automatically unwraps the observables so you can just write with: RootTarget, no parens needed
  • it works for the case when the RootTarget value is null or undified so it hides the inputs while your original solution RootTarget().ID would throw a null reference exception.



回答2:


You need brackets on your roottarget mappings as you need to evaluate the observable before you can get it's properties.

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

Alternatively, RootTarget doesn't actually need to be an observable, only its properties do, so if you remove the line below it'll automatically be created as a normal object and your bindings will work as they are.

this.RootTarget = ko.observable;


来源:https://stackoverflow.com/questions/17612550/mapping-json-with-knockout-fails-to-populate-type-defined-object-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!