PDA

View Full Version : Store asynchronous loading and Form loading



sinbadblue
29 Dec 2010, 12:37 PM
hi folks,

ext js store loading is asynchronous which is nice when performance is critical. however, lack of option to turn this behavior off is quite annoying when dealing with form.

my use case is, an editing form of entity A which contains couple combo boxes use different stores loading reference data from database. when user navigate to this page with an entity id parameter, these combo boxes' stores should finish loading before the form loading entity data by id. Otherwise, the data of these combo boxes won't be populated correctly (combo box populating will fail due to no data in store to look up).

In order to achieve this goal, I turned off autoLoad of all stores, chained these combo boxes via "load" event handler, manually load the combo box A, which call combo box B's load method via "load" event handler, similar combo box C, D, etc. the last combo box Z's "load" event handler will call the form's load method to load the entity data.

my question is, is there a better solution for this use case (ver 3.2)? the load event chaining is so easy to mess up and hard to maintain.

p.s. anyone know why ext js store's loading is asynchronous exclusively?

aramaki
29 Dec 2010, 2:18 PM
you can write function,which will check form elements by XType for example and load data to your combos stores.

slemmon
29 Dec 2010, 3:06 PM
Not 100% sure I understand the scenario, so sorry if I'm off the mark.
It sounds like you have a user coming in with an ID of a record that the form will load with. But, you want the combo boxes in that form to load prior to the form loading whatever record it's received from the user?

What if you masked the form and had a taskRunner running every x seconds to see if each combo box had a view (which I believe is not created until the combo's store has been loaded the first time). If there is no combo view on each combo then do nothing. If there is a view on each combo field then load then load the form, unmask the form, and stop the taskRunner.

That would only work if the combo's store hadn't yet been loaded and no view created. Otherwise maybe have it check to see if the value of each combo was something other than its originalValue property?

zachext
29 Dec 2010, 3:36 PM
This StoreDependencyController might help: http://www.sencha.com/forum/showthread.php?91002

Store loads are asynchronous so that the browser does not freeze while the request is taking place.

firefoxSafari
29 Dec 2010, 8:07 PM
My advice would be to architect the application in such a way that all the data required for display of the form - the values in the form fields as well as the data for the combo stores - could be returned on the same Ajax request. Make the combo mode 'local' and then just use the loadData method on their stores. This could be more performant anyway since you're making one url request instead of three.

Ajax requests might have to be async in Ext-JS but loading the data doesn't have to be.

sinbadblue
30 Dec 2010, 8:12 AM
did you reply to a wrong thread?


you can write function,which will check form elements by XType for example and load data to your combos stores.

sinbadblue
30 Dec 2010, 8:15 AM
put it simple, combo box's store has to be loaded before loading value via form.load method. otherwise, set value on a combo box without pre-loaded store will fail.

thanks for reply anyway


Not 100% sure I understand the scenario, so sorry if I'm off the mark.
It sounds like you have a user coming in with an ID of a record that the form will load with. But, you want the combo boxes in that form to load prior to the form loading whatever record it's received from the user?

What if you masked the form and had a taskRunner running every x seconds to see if each combo box had a view (which I believe is not created until the combo's store has been loaded the first time). If there is no combo view on each combo then do nothing. If there is a view on each combo field then load then load the form, unmask the form, and stop the taskRunner.

That would only work if the combo's store hadn't yet been loaded and no view created. Otherwise maybe have it check to see if the value of each combo was something other than its originalValue property?

sinbadblue
30 Dec 2010, 8:23 AM
hmm, interesting. I am looking for a dependency controller which can handle one component depending on multiple stores. maybe i can implement a similar one.

I understand the benefit of asynchronous, just hope extjs could make it default behavior but not exclusive.


This StoreDependencyController might help: http://www.sencha.com/forum/showthread.php?91002

Store loads are asynchronous so that the browser does not freeze while the request is taking place.

sinbadblue
30 Dec 2010, 8:35 AM
thanks for advise. as you said, still have to deal with async problem(javascript code) if choose this approach. and as a java developer, i managed to not manually write one single javascript code but let spring + helper class (java) to take care of it. really don't want to break this pure java code + extjs standard framework + no customized javascript mode.


so far looks like this is a limitation of current extjs. really wish future version could provide loading dependency control.


My advice would be to architect the application in such a way that all the data required for display of the form - the values in the form fields as well as the data for the combo stores - could be returned on the same Ajax request. Make the combo mode 'local' and then just use the loadData method on their stores. This could be more performant anyway since you're making one url request instead of three.

Ajax requests might have to be async in Ext-JS but loading the data doesn't have to be.

firefoxSafari
30 Dec 2010, 12:26 PM
Still trying to understand this...

So what exactly is the problem? Is it that you have some valueNotFoundText on the combo boxes and then since the stores are not loaded before the form values are this text is still there? If you look at the Ext source code for ComboBox.setValue, it is apparent that the value still gets stored on the combo - it's just the display text that is messed up.

If this is indeed your problem, one possible solution would be to simply call set value on the combo box with it's current value when the store is loaded. It's kind of a hack and there might be a delay in removing the not found text on slower connections, but it would probably work and it could be sander than trying to manually chain the loads. For example,




function appInit() {
var myTextField = new Ext.form.TextField({
fieldLabel: 'First Name',
name: 'first_name'
});



var myCombo = new Ext.form.ComboBox({
fieldLabel: 'State',
name: 'state',
forceSelection: true,
mode: 'local',
triggerAction: 'all',
valueNotFoundText: 'Not found...',
store: ['WI', 'AZ']
});



var form = new Ext.form.FormPanel({
title: 'My Form',
height: 300,
width: 500,
frame: true,
items: [
myTextField,
myCombo
]
});



form.render(Ext.getBody());


form.getForm().setValues({
first_name: 'Tassadar',
state: 'IA'
});


//Hack to fix incorrect valueNotFoundText display...
myCombo.store.on('load', function() {
//If this is commented out, then combo text will be 'Not found...'
myCombo.setValue(myCombo.getValue());
});


myCombo.store.loadData(['WI', 'AZ', 'IA']);
}

Ext.onReady(appInit);

sinbadblue
24 Feb 2011, 10:22 AM
thanks. this is a good alternative to solve the problem. does look like simpler than chaining the loading. will try it out.



Still trying to understand this...

So what exactly is the problem? Is it that you have some valueNotFoundText on the combo boxes and then since the stores are not loaded before the form values are this text is still there? If you look at the Ext source code for ComboBox.setValue, it is apparent that the value still gets stored on the combo - it's just the display text that is messed up.

If this is indeed your problem, one possible solution would be to simply call set value on the combo box with it's current value when the store is loaded. It's kind of a hack and there might be a delay in removing the not found text on slower connections, but it would probably work and it could be sander than trying to manually chain the loads. For example,




function appInit() {
var myTextField = new Ext.form.TextField({
fieldLabel: 'First Name',
name: 'first_name'
});



var myCombo = new Ext.form.ComboBox({
fieldLabel: 'State',
name: 'state',
forceSelection: true,
mode: 'local',
triggerAction: 'all',
valueNotFoundText: 'Not found...',
store: ['WI', 'AZ']
});



var form = new Ext.form.FormPanel({
title: 'My Form',
height: 300,
width: 500,
frame: true,
items: [
myTextField,
myCombo
]
});



form.render(Ext.getBody());


form.getForm().setValues({
first_name: 'Tassadar',
state: 'IA'
});


//Hack to fix incorrect valueNotFoundText display...
myCombo.store.on('load', function() {
//If this is commented out, then combo text will be 'Not found...'
myCombo.setValue(myCombo.getValue());
});


myCombo.store.loadData(['WI', 'AZ', 'IA']);
}

Ext.onReady(appInit);