1

I receive a complex JSON from the server. Let it be next:

var data = [{
    name: "name1",
    items:[
        {
        name:"name11",
        subItems:[{
                name:"name111",
                children[
                    {id:1,name:"child1111",status:"good"},
                    {id:2,name:"child1112",status:"bad"},
                    {id:3,name:"child1113",status:"good"}
                ]},
                {
                name:"name112",
                children[
                    {id:4,name:"child1121",status:"good"}]
                }]
        },
        {
        name:"name12",
        subItems:[{
                name:"name121",
                children[
                    {id:5,name:"child1211",status:"bad"}]
                }]
        }]
    },
    {
    name: "name2",
    items:[
        {
        name:"name21",
        subItems:[{
                name:"name111",
                children[
                {id:7,name:"child2111",status:"good"}
                ]}]
        }]
    }];

So I have the list of objects each one contains name and items properties. Items is property of the similar list of objects each one contains name and subItems properties. subItems property same to previous and has name and children properties. children is list of my entities. I use mapping for filling my ViewModel. First of all I can't image how to set as key id in my entity. I am wondering how to "dive" to it. Moreover, I need to extend my entity. Add the compute property like next example:

computProp: ko.computed(function() {return name+status;})

I don't want to create js classes, because I don't see benefits of mapping on this case. I can implement manual mapping in this case. It would be more clear for me.

So any idea, suggesting or critics are welcome.

PS: I have searched/read similar topics

Community
  • 1
  • 1
RredCat
  • 5,259
  • 5
  • 60
  • 100

1 Answers1

1

You must explicit declare the children viewmodel to get this behaviour, but you still benefit from getting all the mapping done

http://jsfiddle.net/uXMhA/

ChildViewModel = function(data) {
    ko.mapping.fromJS(data, {}, this);
    this.computProp = ko.computed(function() {
        return this.name() + this.status();
    }, this);
};
Anders
  • 17,306
  • 10
  • 76
  • 144
  • So as I get correct - I need to go via loop throw first and second levels and map `children`? Ok, but how in this case can I update them? Go again throw loop? Don't see any advantage and disadvantage - code looks complex then manual update. – RredCat Jan 27 '13 at 19:10
  • You only need to map the children array, the rest is done by the framework. So no its not more complex than manual – Anders Jan 27 '13 at 21:06
  • I still can't get it. Results in jsfiddle are empty in both examples. – RredCat Jan 28 '13 at 08:45
  • Strange only tested in FF though, should not be a problem in other browser, check the error console – Anders Jan 28 '13 at 09:06
  • Looks like I get why - http://stackoverflow.com/questions/5502540/should-github-be-used-as-a-cdn-for-javascript-libraries – RredCat Jan 28 '13 at 09:30
  • :D Yeah, just reload that thing until it gives you a response. Or change the mapping plugin reference. I based that fiddle on a old fiddle... – Anders Jan 28 '13 at 10:15
  • I had create my example based on your jsfiddle and add the key.. Looks like it works. Thanks. – RredCat Jan 28 '13 at 12:22
  • One more question, I want to extend name property one first level ("name11" for example) and second level ("name111"). Is it possible? – RredCat Jan 29 '13 at 14:42
  • 1
    Its a bit more complex since the mapping plugin can only create leafs. You need to map each level seperate like http://jsfiddle.net/uXMhA/2/ – Anders Jan 29 '13 at 16:14
  • Thanks. It isn't worked on jsfiddle, but I copy it to my example. And it still isn't worked but I can see exception reason. This example is crashed on the next point: `ko.applyBindings = function(viewModel, rootNode) {` // rootNode is null and it pass to `applyBindingsToNodeAndDescendantsInternal` method. In this method ko tried to get nodeType (`var isElement = (nodeVerified.nodeType === 1);`) and crashed. I get knockout 2.2.1 and latest mapping plugin (debug) via NuGet. I could try to fix in in ko.. but frankly I don't have a lot of experience in js. – RredCat Jan 30 '13 at 16:24
  • ups. Sorry my fault in my js code. I have call `ko.applyBindings` just in js script body and ko code can't find ` window.document.body`. I have move it to the load function and now it is worked. – RredCat Jan 31 '13 at 08:16