Reputation: 450
I'm using ST2 and using MVC. I'm very new to ExtJS and Sencha, so am not au fair the best practices for many things - and on this issue I've hit a dead end despite research.
I'll use a toy example to illustrate my issue below, but essentially I have a relationship as follows (which all works correctly from an association perspective).
Business X -- Location A
|
-- Location N
I want to then populate the data into (for instance) an Ext.dataview.List
, but to process it such that each location (i.e. child location) has its own separate entry in the table; not just a simple itemTpl
formatting a single entry. However, at present I can't find any way to do that. Is it possible to hook into a List
and format the data as I want, or should I be creating a new store? Ideally I want to make best use of the associations.
As a rough example, each entry would look like this, with some parent data and some child data:
---------------------------
|Smith Co - 1 Smith Street|
---------------------------
|Smith Co - 24 High Street|
---------------------------
|Tea[...] - 12 Tea Leaf |
---------------------------
|Tea[...] - 3 Bis Kit |
---------------------------
[
{
"id":1,
"name":"Smith Co",
"locations":[
{
"address":"1 Smith Street"
},
{
"address":"24 High Street"
}
]
},
{
"id":2,
"name":"Tea So Good",
"locations":[
{
"address":"12 Tea Leaf"
},
{
"address":"3 Bis Kit"
}
]
}
]
Ext.define('Example.model.Location', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'address', type: 'string' }
],
proxy: { ... }, // Rest proxy that loads data as shown above.
BelongsTo: 'Example.model.Company'
}
});
Ext.define('Example.model.Company', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'id', type: 'int' },
{ name: 'name', type: 'string' }
],
proxy: { ... }, // Rest proxy that loads data as shown above.
hasMany: { model: 'Example.model.Location', name: 'locations' }
}
});
Ext.define('Example.store.Companies', {
extend: 'Ext.data.Store',
require: 'Example.model.Company',
config: {
model: 'Example.model.Company'
}
});
// (works correctly, relationships are traversable)
// Companies store is looked up and loaded in #launch()
Ext.define('Example.view.CompaniesList', {
extend: 'Ext.List',
xtype: 'companieslist',
config: {
layout: 'fit',
store: 'Businesses',
itemTpl: [
// Tpl is only to format inside each element
]
}
});
Solution Edit (15th Sept 2013):
I used the solution @rixo suggested (and I had been hoping to avoid in the original question).
I created a separate store for the list, and loaded the data I need into it by using a load
listener on the Companies
store. This seems to be the most graceful solution available, although it means you may need to add extra logic in various places to ensure it remains satisfactorily synchronised.
By pushing the location objects themselves into the new store the associations remain intact (i.e. you can still do location.getCompany()
).
Upvotes: 0
Views: 313
Reputation: 25001
Yes, create another store for locations.
You may have tried a template like this:
itemTpl: [
'{name}',
'<tpl for="locations">',
', {address}',
'</tpl>'
]
But that will indeed only display the information, it won't let you interact with each location as an individual list item.
You could get it working by hacking the view's doRefresh
method, but that's just going against the lib's intention and other developer' expectations.
Maybe the problem is that you can get the data only in this format, that is with locations as children of companies, and you can't get the server to send you a flat list of companies. In that case, I think the most meaningful approach would be to customize a reader to flatten locations from companies, and feed a standalone location store. The extractData
method seems a very promising start for that (see how the JSON reader uses it to implements its root property).
Upvotes: 1