I'm new to Ext and I'm struggling to figure out Models Stores and Proxies.
The server returns one large JSON object. For example.
{
"responseHeader":{
"status":0,
"QTime":12,
"params":{
"facet":"true",
"facet.limit":"40"
}
},
"response":{
"numFound":3806,
"start":0,
"docs":[
{
//Lots of fields
"id":"1234",
...
//Some array properties
"testfield":[
"",
""
],
...
}
]
},
"facet_counts":{
"facet_queries":{
"email":3806
},
"facet_fields":{
"emailaddress":{
},
"subject":{
"candles":136,
"filter":130
},
"fromemail":{
},
//...
},
"facet_dates":{ },
"facet_ranges":{}
},
"highlighting":{
"some doc id":{
"emailtext":[ " Tel.: blah blah <em>blah</em>" ],
"combined":[ "<em>Email</em> To: blah blah blah" ]
}
}
}
I don't want to load this data more than once, I want to grab data from this object, for example the docs object, and put it into a grid. Then pull out another part to put into a selectbox.
How do I load this data once, yet create models and stores to give to grids and selectboxes, from it?
From what I read the proxy holds the servers response? So I tried creating a proxy out side of a store. Thinking I could use the same proxy with more than one store.
var myProxy1 = Ext.create('Ext.data.proxy.Proxy', {
type: 'ajax',
url : '../test',
reader: {
type: 'json',
root: 'responseHeader'
}
});
But when I pass myProxy1 to a store
Ext.define('Test', {
extend: 'Ext.data.Model',
fields: [
{name: 'status', type: 'int'},
{name: 'QTime', type: 'int'},
{name: 'param', type: 'auto'}
]
});
var myStore = Ext.create('Ext.data.Store', {
model: 'Test',
proxy: myProxy1,
autoLoad: true,
listeners:{
load: function( ths, records, successful, operation, eOpts ){
debugger;
}
}
});
It doesn't work. The load event is never fired. No data is loaded. I can see that the proxy made the request, I see the response from the server, but it doesn't load.
If I put the proxy inline it loads.
var myStore = Ext.create('Ext.data.Store', {
model: 'Test',
proxy:{
type: 'ajax',
url : '../test',
reader: {
type: 'json',
root: 'responseHeader'
}
},
autoLoad: true,
listeners:{
load:function( ths, records, successful, operation, eOpts ){
debugger;
}
}
});
I was thinking I could have one proxy, attach it to multiple stores, and just change the reader on it before I load the store.
You are pretty much there, and although I'm pretty sure you are understanding it all, for the benefit of others allow me to give an extended answer and a slightly modified solution to your problem.
Definitions:
You scenario is not an uncommon one - while by default ExtJS loads each store separately, it is likely an application would prefer various stores to be loaded at once through a single read call; for example, when rendering one store-dependent component is dependent on another store.
Your code is not far off from achieving this, but here is how I do it. In effect, when a 'master' (Tasks) store loads, the server response also carries the data of a 'slave' (Tags) store, which is then manually loaded to that 'slave' store.
The 'slave' store (notice autoload: false
and no read operation):
Ext.define('DL.store.Tags', {
extend: 'Ext.data.Store',
model: 'DL.model.Tag',
// Notice the tags are actually returned when the tasks are loaded and loaded into this store by the TasksStore.
autoLoad: false,
autoSync: true,
proxy: {
type: 'direct',
api: {
create: Tags.Create,
update: Tags.Update,
destroy: Tags.Destroy,
},
reader: {
type: 'json',
root: 'tags'
}
},
});
Then the 'master' store:
Ext.define('DL.store.Tasks', {
extend: 'Ext.data.TreeStore',
model: 'DL.model.Task',
autoLoad: true,
autoSync: true,
root: {
text: 'Root',
id: null,
expanded: true
},
proxy: {
type: 'direct',
api: {
create: Tasks.Create,
read: Tasks.Read,
update: Tasks.Update,
destroy: Tasks.Destroy,
},
},
onProxyLoad: function( aOperation )
{
// A read request for tasks will also return the user tags.
// So feed these tags into their store.
var iResult = aOperation.response.result,
iTagsStore = Ext.StoreManager.lookup( 'Tags' );
if ( Ext.isDefined( iResult.tags ) )
iTagsStore.loadRawData( iResult );
// We need this line for "Tasks" store to load its own data
this.callParent(arguments);
}
});
Basically all it does is it takes part of the server response and loads it manually to the 'slave' store.
The PHP server side code (for tasks read operation) involves:
return array(
'success' => true,
'children' => $iNodes,
'tags' => $iTags
);
Where children
is the reader's root of the 'master' store, and tags
is additional data that is then loaded into the 'slave' store.
I hope you can work how how to apply these concepts to your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With