PDA

View Full Version : Ext.data.Batch sample?



cnesbit
6 Mar 2012, 10:39 AM
Hi,

I'm can't seem to find a sample of code using Ext.data.Batch to see if it fits my needs. Maybe someone can suggest a better Ext class for my needs:

I need to load multiple stores when showing a form but would like to consolidate those multiple read AJAX calls into a single AJAX call. In this case, all stores share the same URL so it seems wasteful to me that the user wait for the overhead of multiple server calls when they should only need 1.

Thanks,
cnesbit

mitchellsimoens
6 Mar 2012, 11:35 AM
You could have one store load and setup associations to split off the other stores.

cnesbit
6 Mar 2012, 12:00 PM
You could have one store load and setup associations to split off the other stores.
could you embellish that idea Mitchell? I'm not sure what exactly you're suggesting.

-cnesbit

mitchellsimoens
6 Mar 2012, 12:01 PM
Use hasMany associations. WHen you execute the get method to get the associated data, it returns a Store instance.

cnesbit
6 Mar 2012, 12:14 PM
ok, I read up a bit (briefly) on ExtJS associations and the concept makes sense when dealing with related data.

However, for example, I'm dealing with loading a form that has multiple comboboxes on it that each have a store. None of these stores are at all related to each other in the way an association would imply. I'm just trying to expedite the loading of stores for a screen regardless of how those stores relate (with the only assumption being that they share the same URL).

That being said, how would you go about creating 1 AJAX call out of multiple stores (if you still think associations would work, great. But I guess it currently doesn't make sense to me how since the data isn't necessarily related).

Thanks!

dedoz
7 Mar 2012, 3:50 PM
loading more than one store will end in 1 request, Extjs catches this calls (with a limit of 10 secs if i remember) and then send them all together so doing



personStore = Ext.create('PersonStore');
companyStore = Ext.create('CompanyStore');
personStore.load();
companyStore.load();

ends in 1 only request to the server, you can check theres only 1 request with any browser developer tool.

if u want to "proceed" after everthing is loaded then u can do something like this


personStore = Ext.create('PersonStore');
companyStore = Ext.create('CompanyStore');

personStore.load({callback:afterEverythingIsLoaded});
companyStore.load({callback:afterEverythingIsLoaded});

function afterEverythingIsLoaded()
{ if (personStore.isLoading() || companyStore.isLoading()) return ;
console.log('this is executed after everything is loaded');
}

cnesbit
8 Mar 2012, 5:47 AM
ends in 1 only request to the server, you can check theres only 1 request with any browser developer tool.


...negative. I get seperate calls for each. Here's my store declarations:



Ext.define('MyApp.model.Gender', {
extend: 'Ext.data.Model',
fields: ['Id', 'Description']
});
Ext.define('MyApp.model.Prefix', {
extend: 'Ext.data.Model',
fields: ['Id', 'Description']
});


Ext.define('MyApp.store.Genders', {
extend: 'Ext.data.Store',
model: 'MyApp.model.Gender',
autoLoad: false,

proxy: {
type: 'ajax',
url: 'MyApp.php',
extraParams: {
command: 'genders'
},
reader: {
root: 'genders'
}
}
});
Ext.define('MyApp.store.Prefixes', {
extend: 'Ext.data.Store',
model: 'MyApp.model.Prefix',
autoLoad: false,

proxy: {
type: 'ajax',
url: 'MyApp.php',
extraParams: {
command: 'prefixes'
},
reader: {
root: 'prefixes'
}
}
});


Then I assign my stores to my comboboxes, and in the controller's init function i have this code to load the stores (per dedoz's suggestion).

var Ethnicities=Ext.getStore('Ethnicities'), Genders=Ext.getStore('Genders'),
Prefixes=Ext.getStore('Prefixes'),
States=Ext.getStore('States');
Ethnicities.load();
Genders.load();
Prefixes.load();
States.load();

cnesbit
8 Mar 2012, 5:49 AM
Use hasMany associations. WHen you execute the get method to get the associated data, it returns a Store instance.

This I have also tried. Here's what I've got so far, a store that loads certain other store's data, then propogates it to the other stores. NOTE: I haven't written the "propogating" code yet. Any suggestions for this method of accomplishing my goal?




Ext.define('MyApp.model.Loader', {
extend: 'Ext.data.Model',
fields: ['Id', 'Description'],
proxy: {
type: 'ajax',
url: 'MyApp.php',
extraParams: {
command: Ext.encode(['genders','prefixes'])
}
},
associations: [{
type: 'hasMany',
model: 'Loader',
//primaryKey: 'Id',
//foreignKey: 'parent_id',
autoLoad: false,
associationKey: 'Data' // read child data from child_groups
}]
});


MyApp.model.Loader.load();

mitchellsimoens
8 Mar 2012, 5:52 AM
When the store loads you can execute the get method for the association that is created for you and that will return a store.

cnesbit
8 Mar 2012, 6:34 AM
When the store loads you can execute the get method for the association that is created for you and that will return a store.

not sure if this is what you mean, but it does appear to load the data into the store. when loading data into the form, the values load properly into the comboboxes, however, anytime the combobox's triggers are clicked it causes the error below.

...


Ext.define('MyApp.store.States', {
extend: 'Ext.data.Store',
model: 'MyApp.model.State',
autoLoad: false,
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'States'
}
}
});


Ext.define('MyApp.model.Loader', {
extend: 'Ext.data.Model',
fields: ['Id', 'Description'],
proxy: {
type: 'ajax',
url: 'MyApp.php',
extraParams: {
command: Ext.encode(['Ethnicities','Genders','Prefixes','States'])
}
},
associations: [{
type: 'hasMany',
model: 'Loader',
autoLoad: false,
associationKey: 'Data'
}]
});

MyApp.model.Loader.load(undefined, {
success: function(data) {
for (root in data.raw) {
Ext.getStore(root).loadRawData(data.raw[root]);
console.log(Ext.getStore(root));//store appears to have data
}
}
});

error:
...
loadRecords: function(records, options) {
var me = this,
i = 0,
length = records.length;ERROR: Uncaught TypeError: Cannot read property 'length' of undefined

...

Any more words of wisdom Mitchell?

EDIT: turns out, if I remove my associations it still works the same. So I must not be utilizing the associations properly. Are there any examples of associations doing what I'm trying to do (with potentially un-"associated" data) that I can follow?

EDIT 2: didn't need associations after all, just needed to setup the destination stores with memory proxies, and the loader store as a rest/ajax proxy. The cause of the error above is because I hadn't set queryMode to local on my comoboxes, so when I clicked the trigger it was trying to load from a remote source even though the combo's store had a memory proxy.

cnesbit
9 Mar 2012, 8:47 AM
SETUP:
Create a model, which I call a Loader in this case, that loads any number of datasets into itself. The "destination" stores, which will receive their data from the Loader, have memory proxies. Any comboboxes that use a destination store must have a querymode of local.

OPERATION:
in the Loader's callback, propagate the datasets to their corresponding destination stores.

LIMITATION:
currently, I do not need to save changes to any of the destination store's data. If/When that time comes I suppose I'll need to figure out how to reverse the above process. :)

dedoz
10 Mar 2012, 7:31 PM
...negative. I get seperate calls for each. Here's my store declarations:

can you post how you see this ? because in google chrome using developers tool i see only 1 request that has all the store load params.



Then I assign my stores to my comboboxes, and in the controller's init function i have this code to load the stores (per dedoz's suggestion).

var Ethnicities=Ext.getStore('Ethnicities'), Genders=Ext.getStore('Genders'),
Prefixes=Ext.getStore('Prefixes'),
States=Ext.getStore('States');
Ethnicities.load();
Genders.load();
Prefixes.load();
States.load();


remember that load is asynchronous, and before trying to use the store in a combox you need to sure is loaded (if you are loading like that) that why i posted the "way to proceed after everthing is loaded"

also in general even if theres multiple requests to the server i think your complicating too much the code that ends in more work for you just for a mili second faster code, rembemer loading is asynchronus, is not like the client side will wait for the first store to load and then send the second store load request, they all are sent in 1 call or in many calls but sent at the same time.

cnesbit
15 Mar 2012, 12:24 PM
in google chrome using developers tool i see only 1 request that has all the store load params.
I am using Google chrome with developer tools. And I hate to state the obvious, but the fact that I opened this thread to begin with implies that in google chrome using developers tool I can see more than one server call.

That being said, you and I obviously do not have the same code. Would you mind posting the code you have that produces a single server call so I can see the difference?

Thanks