I have a list that displays a list of restaurants with the logo of the restaurant etc.
The view
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('')
}
});
When you tap the restaurant i want it to show another list based on the item tapped.
The second view
Ext.define('Test.view.Menu', {
extend: 'Ext.List',
xtype: 'contact-menu',
config: {
title: 'Menu',
cls: 'x-contacts',
store: 'Contacts',
itemTpl: [
'<div>{item}</div>'
].join(''),
},
});
The models
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"
});
The store
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'
}
}
}
});
The 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"
}]
}]
}
I want to show a list of menu items (item, item, item...) for the restaurant selectedbut when I use a nested list I have to use the same template as the previous list which doesnt suit my needs. At the moment I get the right amount of items but nothing shows. Can you please help me with where I'm going wrong, thanks.
Before I get to the solution, here are a few problems with your code (which need to be fixed before the solution will work):
In your proxy config within the Contacts
store, the config for the roog of your JSON is rootProperty
, not root
.
proxy: {
type: 'ajax',
url: 'contacts.json',
reader : {
type : 'json',
rootProperty : 'stores'
}
}
You could also just put this code inside your model, as you already put a proxy config in there. Here are both merged (should be inside your model, and remove proxy from the store):
proxy: {
type: 'ajax',
url: 'contacts.json',
reader : {
type : 'json',
rootProperty : 'stores'
}
}
Model names should always be singular as they represent one object. So use Menu
, not Menus
.
You need to require any classes you use inside the class you use them. For example, you need the Sencha.model.Menu
class inside the Sencha.model.Contact
class, so add it inside the requires
property inside Contact.js
:
Ext.define('Sencha.model.Contact', {
extend: 'Ext.data.Model',
requires: ['Sencha.model.Menu'],
...
});
You need to use associationKey
in your hasMany association as normally it would look for menus
(generated from the Model name), but in your JSON is it menu
.
hasMany
and belongsTo
configs should be inside config
block within your models.
Ext.define('Sencha.model.Contact', {
extend: 'Ext.data.Model',
requires: ['Sencha.model.Menu'],
config: {
...
hasMany: {
model: "Sencha.model.Menu",
associationKey: 'menu'
}
}
});
As for the solution :) - you can modify your itemTpl
inside your list to display associated for the record being shown. To do this, you can use:
<tpl for="associatedModelName">
{field_of_associated_model}
</tpl>
So in your case, you can do something like this:
itemTpl: [
'{name}',
'<div>',
'<h2><b>Menu</b></h2>',
'<tpl for="menus">',
'<div> - {item}</div>',
'</tpl>',
'</div>'
].join('')
Here is a download of a project (generated using the SDK Tools) which includes a demo of this, using mostly your code: http://rwd.me/FS57