Показать список из вложенного JSON: Sencha Touch 2 - PullRequest
6 голосов
/ 30 марта 2012

У меня есть список, который отображает список ресторанов с логотипом ресторана и т. Д.

Вид

Ext.define('Test.view.Contacts', {
    extend: 'Ext.List',
    xtype: 'contacts',

    config: {
        title: 'Stores',
        cls: 'x-contacts',

        store: 'Contacts',
        itemTpl: [
            '<div class="headshot" style="background-image:url(resources/images/logos/{logo});"></div>',
            '{name}',
            '<span>{add1}</span>'
        ].join('')
    }
});

Когда вы нажимаете на ресторан, я хочу, чтобы он отображал другой список, основанный на постучанном предмете.

Второй вид

Ext.define('Test.view.Menu', {
    extend: 'Ext.List',
    xtype: 'contact-menu',

    config: {
        title: 'Menu',
        cls: 'x-contacts',

        store: 'Contacts',
        itemTpl: [
            '<div>{item}</div>'
        ].join(''),
    },
});

Модели

Ext.define('Test.model.Contact', {
    extend: 'Ext.data.Model',

    config: {
        fields: [
            'name',
            'logo',
            'desc',
            'telephone',
            'city',
            'add1',
            'post',
            'country',
            'latitude',
            'longitude'
        ],
        proxy: {
            type: 'ajax',
            url: 'contacts.json'
        }
    },
    hasMany: {
        model: "Test.model.Menus",
        name: 'menus'
    }
});

Ext.define('Test.model.Menus', {
    extend: 'Ext.data.Model',
    config: {
        fields: [
            'item'
        ]
    },
    belongsTo: "Test.model.Contact"
});

В магазине

Ext.define('Test.store.Contacts', {
  extend: 'Ext.data.Store',

  config: {
    model: 'Test.model.Contact',
    autoLoad: true,
    //sorters: 'name',
    grouper: {
      groupFn: function(record) {
        return record.get('name')[0];
      }
    },
    proxy: {
      type: 'ajax',
      url: 'contacts.json',
      reader: {
        type: 'json',
        root: 'stores'
      }
    }
  }
});

JSON

{
    "stores": [{
        "name": "Science Gallery",
        "logo": "sciencegallery.jpg",
        "desc": "Get some food",
        "telephone": "016261234",
        "city": "Dublin",
        "add1": "Pearse Street",
        "post": "2",
        "country": "Ireland",
        "latitude": "53.34422",
        "longitude": "-6.25006",
        "menu": [{
            "item": "SC Sandwich"
        }, {
            "item": "SC Toasted Sandwich"
        }, {
            "item": "SC Panini"
        }, {
            "item": "SC Ciabatta"
        }, {
            "item": "SC Burrito"
        }]
    }, {
        "name": "Spar",
        "logo": "spar.jpg",
        "desc": "Get some food",
        "telephone": "016261234",
        "city": "Dublin",
        "add1": "Mayor Street",
        "post": "2",
        "country": "Ireland",
        "latitude": "53.34422",
        "longitude": "-6.25006",
        "menu": [{
            "item": "Spar Sandwich"
        }, {
            "item": "Spar Toasted Sandwich"
        }, {
            "item": "Spar Panini"
        }, {
            "item": "Spar Ciabatta"
        }, {
            "item": "Spar Burrito"
        }]
    }]
}

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

1 Ответ

12 голосов
/ 31 марта 2012

Прежде чем я доберусь до решения, вот несколько проблем с вашим кодом (которые должны быть исправлены, прежде чем решение будет работать):

  • В вашей конфигурации прокси в Contacts store, конфигурация для roog вашего JSON: rootProperty, а не root.

    proxy: {
        type: 'ajax',
        url: 'contacts.json',
        reader : {
            type : 'json',
            rootProperty : 'stores'
        }
    }
    

    Вы также можете просто поместить этот код в вашу модель, так как вы уже добавили конфигурацию прокси втам.Вот оба слияния (должны быть внутри вашей модели и удаления прокси из хранилища):

    proxy: {
        type: 'ajax',
        url: 'contacts.json',
        reader : {
            type : 'json',
            rootProperty : 'stores'
        }
    }
    
  • Имена моделей всегда должны быть единичными, поскольку они представляют один объект.Так что используйте Menu, а не Menus.

  • Вам нужно требовать любые классы, которые вы используете внутри класса, в котором вы их используете.Например, вам нужен класс Sencha.model.Menu внутри класса Sencha.model.Contact, поэтому добавьте его в свойство requires внутри Contact.js:

    Ext.define('Sencha.model.Contact', {
        extend: 'Ext.data.Model',
        requires: ['Sencha.model.Menu'],
    
        ...
    });
    
  • Вам необходимо использоватьassociationKey в вашей ассоциации hasMany, как обычно, будет выглядеть menus (генерируется из названия модели), но в вашем JSON это menu.

  • hasMany иbelongsTo конфиги должны быть внутри блока config в ваших моделях.

    Ext.define('Sencha.model.Contact', {
        extend: 'Ext.data.Model',
        requires: ['Sencha.model.Menu'],
    
        config: {
            ...
    
            hasMany: {
                model: "Sencha.model.Menu",
                associationKey: 'menu'
            }
        }
    });
    

Что касается решения :) - вы можете изменить itemTplвнутри вашего списка, чтобы отобразить связанные записи.Для этого вы можете использовать:

<tpl for="associatedModelName">
     {field_of_associated_model}
</tpl> 

Так что в вашем случае вы можете сделать что-то вроде этого:

itemTpl: [
    '{name}',
    '<div>',
        '<h2><b>Menu</b></h2>',
        '<tpl for="menus">',
            '<div> - {item}</div>',
        '</tpl>',
    '</div>'
].join('')

Вот загрузка проекта (сгенерированного с помощью SDKИнструменты), которая включает демонстрацию этого, используя в основном ваш код: http://rwd.me/FS57

...