How to read nested JSON structure using Sencha Touch data model?

I tried to figure it out all evening, but to no avail. I have a JSON structure as follows (coming from another system, so I cannot 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 cannot understand what the correct structure should be for data models. I tried the following, but that will not work. By the way, I can access parent information. The problem is access to child information. So, I think that something is wrong with how I established 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 data warehouse:

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

I use the following template, which receives parent information for me, but I cannot receive 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 that both the "child" and the "parent" elements are surrounded by another element, "children" and "parents", respectively.

Any help is greatly appreciated.

Thanks in advance,

Philip

PS If I remove the external "child" element and just leave the internal "child" element (and change "child.child" to "child" in the model definition), the code works fine.

PPS I answer my question:

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

It should be as follows (note: I did not need to specify the hasMany or 'association' elements - not too sure why this is so or what their inclusion is):

     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 also works fine:

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

+8
json nested extjs
source share
2 answers

I added a converter to allow the template to access data in the model sequentially, regardless of whether a single object or array is returned.

Ext.regModel("ParentModel", { fields: [ {name: 'parentId', type: 'string'}, {name: 'children', convert: function(value, record) { if (value.child) { if (value.child instanceof Array) { return value.child; } else { return [value.child]; // Convert to an Array } } return value.child; } } ], proxy: { type: 'ajax', url : 'models.json', reader: { type: 'json', root: 'parents.parent' // this works fine } } }); 

Note. I really don't need to define the Kids function. I think I can leave without defining it, since Sencha should automatically convert it.

+7
source share

Recently, a similar problem has arisen. I think.

You need to specify a 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" } 

},


+11
source share

All Articles