Search code examples
javascriptjsonknockout.jsknockout-mapping-plugin

Bind complex JSON object using knockout.js


I'm brand new to using Knockout.js and have just installed/instantiated a ViewModel binding using ko.mapping.js only to find that I get a partial binding.

Using the example code listed below we see that the binding works for the simple data but not the complex data in the JSON object. Here's a Fiddle


Complex JSON object:

 var json = {
    "a": "A",
    "b": [{
           "b1": "B1",
           "b2": "B2",
           "b3": [{ "one": "One", "two": "Two"}]
         }],
    "c": "C"
 }


HTML Elements to bind to:

<div data-bind="text: a"></div>
<div data-bind="text: b.b1"></div>
<div data-bind="text: c"></div>


Javascript ViewModel/binding:

var vm = {};    
vm = ko.mapping.fromJS(json);
ko.applyBindings(vm);


Have I missed something?

In Knockout.js, is it possible to bind a complex JSON object to a viewmodel using knockout.mapping.js?

If not, using this example ...how can we bind this complex JSON object using knockout.js?

The closest existing StackOverflow post I've been able to find is this one, Knockout mapping complex object and I've tried for hours now utilizing multiple approaches and have been unsuccessful in being able to you the ko.mapping.js to do this binding.

And unfortunately the Knockoutjs.com documentation (http://knockoutjs.com/documentation/plugins-mapping.html) doesn't cover whether or not this is even possible with the plugin.


Solution

  • ko.mapping.js handles simple as well as complex object implicitly. Actually there is problem in binding which is used to access nested object.

    As you see property b is an array so ko.mapping will convert it into observableArray.so binding will be like this :-

    <div data-bind="text: a"></div>
    <div data-bind="text: b()[0].b1"></div> //As b is array
    <div data-bind="text: c"></div>
    

    Below you can see the object after mapping.

    {
    "a": "A",
    "b": [
        {
            "b1": "B1",
            "b2": "B2",
            "b3": [
                {
                    "one": "One",
                    "two": "Two"
                }
            ]
        }
    ],
    "c": "C",
    "__ko_mapping__": {
        "ignore": [],
        "include": [
            "_destroy"
        ],
        "copy": [],
        "observe": [],
        "mappedProperties": {
            "a": true,
            "b[0].b1": true,
            "b[0].b2": true,
            "b[0].b3[0].one": true,
            "b[0].b3[0].two": true,
            "b[0].b3": true,
            "b": true,
            "c": true
        },
        "copiedProperties": {}
    }
    }
    

    Fiddle Demo