0

I'm trying to load nested JSONData into my tree grid. On the first call to get data, all the data needed to populate the grid is returned in the response as a JSON Object. However I can see that it still tries fetch data for all the parent objects in the grid.

Even after the spurious GETs, it is still unable to populate the child Nodes.

I've defined 2 models, the parent with a "hasMany" relationship referring to the child model, and the child node with "BelongsTo" relationship referring to the parent model

I'm using an Ajax Proxy with a JSON reader.

Searching the web I can't find much information and I've used the user-orderitems-products example in the extJS documentation to try and set up the my models and tree.

I'm not entirely sure what I'm missing. Any assistance would be much appreciated.

JSON (person may or may not have children objects):

People: {
 {firstName: john, id:123, uniqueID:1231, leaf:true},
 {firstName: jane, id:124, uniqueID:1240, 
  offspring:[
    {firstName: adam,    id:124,  uniqueID:1241, leaf:true},
    {firstName: brandon, id:124,  uniqueID:1242, leaf:true},
    {firstName: claire,  id:1243, uniqueID:1243, leaf:true}
 ]}
}

Model:

Ext.define('Person',{
  extend: 'Ext.data.Model',
  fields: [
    {name: 'firstName', type:'string'},
    {name: 'uniqueID',  type:'float'}
    hasMany: {
       model:'Offspring', 
       name: 'Offspring', 
       associationKey: 'offspring',
       primaryKey: 'uniqueID',
       foreignKey: 'id'
    }
  ],
  proxy: {
   type: 'rest',
   url: 'http://blah/blah',
   reader: {
     type: 'json',
     root: 'People'
   }

  }
});

Ext.define('Offspring',{
  extend: 'Ext.data.Model',
  fields: [
    {name: 'firstName', type:'string'},
    {name: 'uniqueID',  type:'float'}
 ],
 belongsTo: 'Person'
});

Store Definition:

var store = Ext.create('Ext.data.TreeStore', {
  model: 'Person',
  folderSort: true
}
Babyangel
  • 105
  • 1
  • 2
  • 10

2 Answers2

2

I suspect you might be confusing a simple parent-child relationship with hasMany relationship.

But for your original question. You are returning a node (jane) which is not a leaf, but has no children returned. As your proxy root for Person is People, the children property should also be people.

I believe the following JSON will work for you:

People: {
    {firstName: john, id:123, uniqueID:1231, leaf:true},
    {firstName: jane, id:124, uniqueID:1240, 
    People:[
        {firstName: adam,    id:124,  uniqueID:1241, leaf:true},
        {firstName: brandon, id:124,  uniqueID:1242, leaf:true},
        {firstName: claire,  id:1243, uniqueID:1243, leaf:true}
    ]}
}

Here is a working code:

Model:

Ext.define('BS.model.ItemCategory', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'name'     , type: 'string'},
        {name: 'iconCls'  , type: 'string', defaultValue: 'treenode-no-icon'},
        {name: 'leaf'     , type: 'boolean', defaultValue: false},
        {name: 'expanded' , type: 'boolean', defaultValue: true, persist: false},
        {name: 'index'     , type: 'int'},        
    ],

    proxy: {
        type: 'direct',

        api: {
            create:  ItemCategories.Create,
            read:    ItemCategories.Read,
            update:  ItemCategories.Update,
            destroy: ItemCategories.Destroy,
        },
    },

});

Store:

Ext.define('BS.store.ItemCategories', {

    extend: 'Ext.data.TreeStore',    
    model: 'BS.model.ItemCategory',

    autoSync: true,

    root: {
        text: 'Root',
        id: 'NULL',
        expanded: true
    },

    clearOnLoad: true,
});

JSON:

"result":{
  "success":true,
  "children":[
     {
        "id":"1",
        "parentId":null,
        "name":"DFM",
        "index":"0",
        "deleted":"0",
        "children":[
           {
              "id":"6",
              "parentId":"1",
              "name":"Studios",
              "index":"0",
              "deleted":"0",
              "loaded":true,
              "leaf":false
           },
           {
              "id":"7",
              "parentId":"1",
              "name":"Equipment",
              "index":"1",
              "deleted":"0",
              "children":[
                 {
                    "id":"18",
                    "parentId":"7",
                    "name":"Cameras",
                    "index":"0",
                    "deleted":"0",
                    "loaded":true,
                    "leaf":false
                 },
                 {
                    "id":"20",
                    "parentId":"7",
                    "name":"Tripods",
                    "index":"1",
                    "deleted":"0",
                    "loaded":true,
                    "leaf":false
                 },
                 {
                    "id":"26",
                    "parentId":"7",
                    "name":"Lighting Kits",
                    "index":"2",
                    "deleted":"0",
                    "loaded":true,
                    "leaf":false
                 }
              ],
              "leaf":false
           }
        ],
        "leaf":false
     },
     {
        "id":"3",
        "parentId":null,
        "name":"3D",
        "index":"2",
        "deleted":"0",
        "loaded":true,
        "leaf":false
     }
  ]
}
Izhaki
  • 23,372
  • 9
  • 69
  • 107
  • When I try that I get: 'node is undefined'. when its parsing through the appendChild method and tries to do oldParent=node.parentNode – Babyangel Jun 29 '12 at 04:51
  • Even if I add 'people' as the child node and remove the has Many belongs to definitions in the model I still get the error. – Babyangel Jun 29 '12 at 05:01
  • That's most likely because ExtJS doesn't wrap the model with NodeInterface. Could you try loading via a store that extends `Ext.data.TreeStore`? – Izhaki Jun 29 '12 at 09:51
  • my current store is an instance of Ext.data.TreeStore. Added definition to original question. I should explicitly extend treestore? – Babyangel Jun 29 '12 at 11:14
  • I'm not sure but I'd try it as there's some code for stores dealing explicitly with subclasses and their model. – Izhaki Jun 29 '12 at 11:22
  • I tried it. Still getting the same problem. I did a Ext.define('myStore', {extend: 'Ext.data.TreeStore'}); – Babyangel Jun 29 '12 at 11:31
  • When I look at your code. The root People isn't wrapped as an array, which might be the issue. – Izhaki Jun 29 '12 at 16:44
  • I made my json similar using results and children, but its still loading just firt hierarchy, but it isnt trying to load kids anymore. But i think its not registering that there are leaf nodes. Leaf is set to false on top layer. – Babyangel Jul 02 '12 at 10:47
  • Is your root still set to `People`? If yes can you comment that? And can you set folderSort to false, just in case? – Izhaki Jul 02 '12 at 11:06
  • On closer inspection, it looks like the last node is what is on display. So using your example, imagine you only returned one category "equipment" with all its children. And what is on display is "lighting kits". Folder sort is set to false. – Babyangel Jul 04 '12 at 18:06
  • Discovered something interesting, when i toggle sort the full data appears but i'm gett error- record[i] is undefined. ns[i].viewRecordId = records[i].internalId – Babyangel Jul 04 '12 at 18:49
  • Didn't need to use jsFiddle. The above error made me think there was something wrong with the way records were being processed. As well as making your changes I added an idProperty: 'uniqueID' to the model and that seems to fix it. the data that gets returned has a field 'ID' that is not actually unique. and idProperty defaults to 'ID'. That seemed to be causing problems. Thanks for all the help! – Babyangel Jul 09 '12 at 15:15
1

There's an example of exactly this in the SDK download: http://dev.sencha.com/deploy/ext-4.1.0-gpl/examples/tree/treegrid.html

Evan Trimboli
  • 29,900
  • 6
  • 45
  • 66
  • I started off with that as my template code. I'm trying to understand why I can't get my tree to render event though the example does. – Babyangel Jun 29 '12 at 05:00
  • Even after I format my JSON so that it looks like the JSON in that example (using text:"." and child name "children") I'm still getting the node undefined error. – Babyangel Jun 29 '12 at 08:41