开发者

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

开发者 https://www.devze.com 2023-04-11 16:20 出处:网络
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):

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>',


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"
  }

},



I've added a converter to allow the template access the data in the model consistently regardless if a single object or an 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 don't actually need to define the ChildrenModel. I guess I can get away without defining it as Sencha must be automatically type converting it.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号