Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read nested JSON structure with a Sencha Touch Data Model?

Tags:

json

nested

extjs

I've been trying to figure this out all evening but to no avail. I have a JSON structure as follows (coming from another system so I can't change its structure):


    {
        "parents":{
            "parent":[
             {
                 "parentId":1,
                 "children":{
                     "child":[
                      {
                          "childId":1,
                      },
                      {
                          "childId":2,
                      }
                   ]
                }
             },
             {
                "parentId":2,
                "children":{
                   "child":[
                      {
                         "childId":1,
                      },
                      {
                         "childId":2,
                      }
                   ]
                }
             }
          ],
          "pageNum":1,
          "pageSize":2
       }
    }

However, I can't figure out what the correct structure for the data models should be. I've tried the following but it does not work. BTW, I can access the parent information. The issue is with accessing the child information. So, I guess there is something wrong with how I've set up the relationship data.


    Ext.regModel("ParentModel", {
        hasMany: { 
            model: 'ChildrenModel', 
            name: 'children.child' // not too sure about this bit
        },
        fields: [
            {name: 'parentId', type: 'string'}
        ],

        proxy: {
            type: 'ajax',
            url : 'models.json',
            reader: {
                type: 'json',
                root: 'parents.parent' // this works fine
            }
        }
    });

    Ext.regModel('ChildrenModel', {
        belongsTo: 'ParentModel', // not too sure about this bit
        fields: [{name: 'childId', type: 'string'}]
    });

with a data store:


    Ext.regStore('ParentModelStore', {
        model: 'ParentModel',
        autoLoad:true
    });

I'm using the following template which gets me the parent information, but I can't get the child data from it:


    myapp.views.ParentView = Ext.extend(Ext.Panel, {
        layout: 'card',

        initComponent: function() {
            this.list = new Ext.List({
                itemTpl: new Ext.XTemplate(
                    '<tpl for=".">',
                        '<div>',
                            '{parentId}', // this works fine
                        '</div>',
                        '<tpl for="children.child">', // this doesn't work
                              {childId}
                        '</tpl>',
                    '</tpl>',
                ),
                store: 'ParentStore',
            });

            this.listpanel = new Ext.Panel({
                layout: 'fit',
                items: this.list,
            });

            this.items = this.listpanel;

            myapp.views.ParentView.superclass.initComponent.apply(this, arguments);
        },

    });

    Ext.reg('ParentView', myapp.views.ParentView);

What I'm struggling with is the fact that both the "child" and "parent" elements are surrounded by another element, "children" and "parents" respectively.

Any help much appreciated.

Thanks in advance,

Philip

PS If I remove the outer "children" wrapping element and just leave the inner "child" element (and change "children.child" to "child" in the model definition) the code works fine.

PPS I'm answering my own question:

Doh! I forgot to add the "children" element to the ParentModel's fields.

It should be as follows (note: I didn't need to specify the 'hasMany' or 'associations' elements - not too sure why this is or what is the benefit of including them):


    Ext.regModel("ParentModel", {
        fields: [
            {name: 'parentId', type: 'string'},
            {name: 'children'} // VERY IMPORTANT TO ADD THIS FIELD
        ],

        proxy: {
            type: 'ajax',
            url : 'models.json',
            reader: {
                type: 'json',
                root: 'parents.parent' // this works fine
            }
        }
    });

    Ext.regModel('ChildrenModel', {
        fields: [{name: 'childId', type: 'string'}]
    });

The template works fine too:


    '<tpl for="children.child">', // this syntax works too.
          {childId}
    '</tpl>',

like image 452
Philip Murphy Avatar asked Oct 09 '11 23:10

Philip Murphy


1 Answers

Ran into a similar problem recently..I think.

You need to specify the mapping to the data you want in your model. For example :

Ext.regModel('Album', {
fields: [
    {name: 'artist_name', mapping: 'album.artist.name'},
    {name: 'artist_token', mapping: 'album.artist.token'},
    {name: 'album_name', mapping: 'album.name'},
    {name: 'token', mapping: 'album.token'},
    {name: 'small_cover_url', mapping: 'album.covers.s'},
    {name: 'large_cover_url', mapping: 'album.covers.l'}
]/*,
getGroupString : function(record) {
    return record.get('artist.name')[0];
},*/

});

consumes this JSON:

   {
  "album":{
     "covers":{
        "l":"http://media.audiobox.fm/images/albums/V3eQTPoJ/l.jpg?1318110127",
        "m":"http://media.audiobox.fm/images/albums/V3eQTPoJ/m.jpg?1318110127",
        "s":"http://media.audiobox.fm/images/albums/V3eQTPoJ/s.jpg?1318110127"
     },
     "artist":{
        "name":"New Order",
        "token":"OyOZqwkN"
     },
     "name":"(The Best Of)",
     "token":"V3eQTPoJ"
  }

},


like image 174
mwrf Avatar answered Sep 24 '22 04:09

mwrf