Как читать вложенную структуру JSON с помощью модели данных Sencha Touch? - PullRequest
8 голосов
/ 10 октября 2011

Я пытался понять это весь вечер, но безрезультатно. У меня есть структура JSON следующим образом (из другой системы, поэтому я не могу изменить ее структуру):


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

Однако я не могу понять, какой должна быть правильная структура для моделей данных. Я пробовал следующее, но это не работает. Кстати, я могу получить доступ к родительской информации. Проблема заключается в доступе к детской информации. Итак, я думаю, что-то не так с тем, как я настроил данные отношений.


    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'}]
    });

с хранилищем данных:


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

Я использую следующий шаблон, который возвращает мне родительскую информацию, но я не могу получить дочерние данные из нее:


    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);

С чем я борюсь, так это с тем, что оба элемента: "child" и "parent" окружены другим элементом, соответственно "children" и "parent".

Любая помощь высоко ценится.

Заранее спасибо,

Philip

PS Если я удаляю внешний оберточный элемент «children» и просто оставляю внутренний «child» элемент (и меняю «children.child» на «child» в определении модели), код работает нормально.

PPS Я отвечаю на свой вопрос:

Doh! Я забыл добавить элемент "children" в поля ParentModel.

Это должно быть следующим (примечание: мне не нужно было указывать элементы 'hasMany' или 'ассоциаций' - не слишком уверен, почему это так и в чем их преимущество):


    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'}]
    });

Шаблон тоже отлично работает:


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

Ответы [ 2 ]

11 голосов
/ 10 октября 2011

Недавно столкнулся с подобной проблемой .. Я думаю.

Вам необходимо указать отображение на данные, которые вы хотите в своей модели.Например:

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];
},*/

});

использует этот 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"
  }

},


7 голосов
/ 21 октября 2011

Я добавил конвертер, чтобы шаблон мог последовательно получать доступ к данным в модели независимо от того, возвращен ли один объект или массив.

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
            }
        }
    });

Примечание. На самом деле мне не нужно определять ChildrenModel. Полагаю, я могу уйти, не определив его, поскольку Сенча должен автоматически преобразовать текст.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...