PDA

View Full Version : Slide first, load after using tabpanels



slmd
2 Nov 2011, 7:26 AM
Hi all,

I am almost done coding my app and about to realease it in a few but i am seriously doubting about the performances of my app for the simple reason transitions are slow. As said in the title, i am using tabpanels retrieving lists of items from externals Json files. In order to improve my application transitions, i am thinking of loading the lists after the slide event and show a loading while the list is being loaded. Is there anything i can read about that or any example someone helpfull can show me to achieve this?

Thank you

AndreaCammarata
3 Nov 2011, 2:02 AM
Hi slmd.
If I weel understand your application architecture, you have a TabPanel which contains some lists loaded from external json files and this lists are all loaded on application startup.
Am I correct?

slmd
3 Nov 2011, 2:59 AM
here is a small working program illustrating the basic architechture of my application so you guys can have a concrete idea about what i am talking about. It can also hopefully helps beginners to build their first program quickly.

//Json file


{
"profile": [{
"firstname": "firstname1",
"lastname": "lastname1",
"age": "1"
},{
"firstname": "firstname2",
"lastname": "lastname2",
"age": "2"
},{
"firstname": "firstname3",
"lastname": "lastname3",
"age": "3"
}]
}


//Store


Ext.regModel('demoApp', {
fields: [
{name: 'firstname', type: 'string'},
{name: 'lastname', type: 'string'},
{name: 'age', type: 'number'}
]
})


var AppStore = new Ext.data.Store({
model: 'demoApp',
sorters: 'lastname',
proxy: {
type: 'ajax',
url: '/data.json',
reader: {
type: 'tree',
root: 'profile'
}
},
autoload: true
})


//template


var listTpl = new Ext.XTemplate(
'<tpl for=".">',
'<div class="profile">',
'<h1>{lastname} {firstname} -> {age} years old',
'</div>',
'</tpl>'
)


//panel 3


var panel3List = new Ext.List({
layout: 'fit',
store: AppStore,
itemTpl: listTpl
})


var panel3 = Ext.extend(Ext.Panel,{
layout: 'card',

initComponent: function(){
this.items = panel3List;

panel3.superclass.initComponent.call(this);
}
});
Ext.reg('panel3', panel3);


//panel 2


var panel2List = new Ext.List({
layout: 'fit',
store: AppStore,
itemTpl: listTpl
})


var panel2 = Ext.extend(Ext.Panel,{
layout: 'card',

initComponent: function(){
this.items = panel2List;

panel2.superclass.initComponent.call(this);
}
});
Ext.reg('panel2', panel2);


//panel 1






var panel1List = new Ext.List({
layout: 'fit',
store: AppStore,
itemTpl: listTpl
})


var panel1 = Ext.extend(Ext.Panel,{
layout: 'card',

initComponent: function(){
this.items = panel1List;

panel1.superclass.initComponent.call(this);
}
});
Ext.reg('panel1', panel1);


//tabpanels


Ext.setup({
fullscreen: true,

onReady: function(){


var appli = new Ext.TabPanel({
fullscreen: true,
cardswitchanimation: 'slide',
items: [{
xtype: 'panel1',
iconCls: 'more',
title: 'Panel1'
},{
xtype: 'panel2',
iconCls: 'more',
title: 'Panel2'
},{
xtype: 'panel3',
iconCls: 'more',
title: 'Panel3'
}],

tabBar: {
dock: 'bottom',
layout: {pack: 'center'}
}
})
}
})


//index.html


<!DOCTYPE >
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" title="design" href="libs/touch/resources/css/sencha-touch.css" />
<script language="JavaScript" src="libs/touch/sencha-touch.js"></script>

<script language="JavaScript" src="tpl.js"></script>
<script language="JavaScript" src="store.js"></script>

<script language="JavaScript" src="panel3.js"></script>
<script language="JavaScript" src="panel2.js"></script>
<script language="JavaScript" src="panel1.js"></script>

<script language="JavaScript" src="tabpanels.js"></script>
</head>

<body></body>
</html>


This program is loading an external Json file and at the same time try to render the corresponding view which cause the application to be very slow and late responsive. What i want to do is first: slide to the corresponding panel and second: load the corresponding datas from the json and show a loader while this is happening

Thank you

slmd
3 Nov 2011, 3:03 AM
Thanks for your reply andreacammarata. I've just posted some code illustrating how my porgram is structured. Don't hesitate if you have other questions.

AndreaCammarata
3 Nov 2011, 3:29 AM
Hi slmd.
Before to suggest you a solution, I just have a question:
There is a particular reason why you wrap your lists inside panels?
If every card of your TabPanel should contains only a list, then you can set lists directly as your TabPanel items without wrapping them inside panels.

And another question:
I suppose that every list should contains different data isn't? Not the same store for every list, am I correct?

slmd
3 Nov 2011, 4:59 AM
To reply to your first question, the reason why i am wrapping my list inside a panel is that i am also using a toolbar for each panel. But in order not to confuse people that decided to help me i voluntarly decided not to include that part of the code.
And finaly, talking about the list, Yes! Every list should contain different datas and as explained above, i voluntarly decided to keep the code as short as possible.

AndreaCammarata
3 Nov 2011, 5:55 AM
Ok, I will write you a complete solution to your problem.
First suppose you have three different json data to load in three different stores.
So:

data1.json



{ "profile": [{ "firstname": "firstname1", "lastname": "lastname1", "age": "1" },{ "firstname": "firstname2", "lastname": "lastname2", "age": "2" },{ "firstname": "firstname3", "lastname": "lastname3", "age": "3" }]}

data2.json



{ "profile": [{ "firstname": "firstname4", "lastname": "lastname4", "age": "4" },{ "firstname": "firstname5", "lastname": "lastname5", "age": "5" },{ "firstname": "firstname6", "lastname": "lastname6", "age": "6" }]}

data3.json



{ "profile": [{ "firstname": "firstname7", "lastname": "lastname7", "age": "7" },{ "firstname": "firstname8", "lastname": "lastname8", "age": "8" },{ "firstname": "firstname9", "lastname": "lastname9", "age": "9" }]}

Then your data model is ok, but you need to define three different stores in this way



Ext.regStore('appStore1',{
model: 'demoApp',
sorters: 'lastname',
proxy: {
type: 'ajax',
url: 'data.json',
reader: {
type: 'json',
root: 'profile'
}
}
})



The other two stores will be called respectively "appStore2" and "appStore3".
Notice that I removed the "autoLoad" config, because we want to load the stores manually.

Finally, your application should be coded like follows:



Ext.setup({
fullscreen: true,

onReady: function(){




var appli = new Ext.TabPanel({
fullscreen: true,
cardswitchanimation: 'slide',
tabBar: {
dock: 'bottom',
layout: {pack: 'center'}
},
items: [{
xtype: 'list',
iconCls: 'more',
title: 'List1',
store:'appStore1',
itemTpl: listTpl
},{
xtype: 'list',
iconCls: 'more',
title: 'Panel2',
store:'appStore2',
itemTpl: listTpl

},{
xtype: 'list',
iconCls: 'more',
title: 'Panel3',
store:'appStore3',
itemTpl: listTpl

}],
listeners: {
beforecardswitch: function(tabPanel, newCard){

/* Getting the list store that is going to set as active inside
* the TabPanel and load the data */
newCard.getStore.load();


}
}
});


}
})


As you can see, I've added a "beforecardswitch" listener to the TapPanel.
In this way, when the user tap on a Tab button to show the wanted list, just before the list is showed, I reload the store data.

If you have any question don't hesitate to ask.

Hope this helps.

slmd
3 Nov 2011, 7:09 AM
Thank you for your reply. We are almost there. I've tried this code but i am having this error "Uncaught TypeError: Cannot call method 'load' of undefined". On the other side, what i want is the list to be loaded after the slide so i guess i should use the afterlayout event. What do you think?

AndreaCammarata
3 Nov 2011, 7:12 AM
Sorry, my mistake, I forgot the brackets



newCard.getStore().load();


You should use the "cardswitch" listener instead of "beforecardswitch".

Hope this helps.

slmd
3 Nov 2011, 7:21 AM
Sorry, but it still doesn't work :(

AndreaCammarata
3 Nov 2011, 7:25 AM
What's the error from your javascript console?
If inside the "cardswitch" listener you log the store calling



console.log(newCard.getStore());


what do you see from the console?

slmd
3 Nov 2011, 7:51 AM
I am having the same error "Uncaught TypeError: Object [object Object] has no method 'getStore'"

AndreaCammarata
3 Nov 2011, 7:54 AM
Did you place your Panels wrapper as tab of your TabPanel or how I show you directly the list components?

slmd
3 Nov 2011, 8:16 AM
i have made all the necessary changes. I've also tried to hide these two lines within the panels


store: AppStore,
itemTpl: listTpl

and ended up having this as an error: "Uncaught Error: Ext.List: itemTpl is a required configuration." which is what i was expecting but i am desperate right now and trying everything.

AndreaCammarata
3 Nov 2011, 8:22 AM
Can you post me your actual application code because something is not clear:
You said that you comment those two lines, and the error is right because itemTpl is a required configuration for List components, but as I showed you the store config as to be "appStore1" or "appStore2" or "appStore3" in string format.
You are trying to set an object that doesn't exist anymore if you followed my instructions.

slmd
3 Nov 2011, 8:30 AM
I am so sorry. It's working perfect. I've just noticed you changed the xtypes to list therefore i don't need panels anymore. Next step, i just have to adapt it to my code.
I've noticed that the loader is not middle placed plus the transparent background disappears right after the slide. How can i deal with that?
Thank you very much and thank you for your patience

slmd
3 Nov 2011, 8:44 AM
Nevermind i made that happen. I've simply used cardswitch event. Many thanks

AndreaCammarata
3 Nov 2011, 8:48 AM
You are welcome slmd.

slmd
4 Nov 2011, 1:47 AM
Hi!
Sorry to bother with this again but i've noticed that the list is not loaded on application startup. How can i make it happen?
Thanks

AndreaCammarata
4 Nov 2011, 1:49 AM
Hi.
What do you mean that the application is not loaded on startup?
Do you maybe mean that the first tab list store is not loaded on application startup?

slmd
4 Nov 2011, 2:15 AM
Sorry i've corrected right after i've submitted it. What i meant is, on application startup the store is not loaded :)

AndreaCammarata
4 Nov 2011, 2:20 AM
Ok :).
So it's simple...just set the "autoLoad" config to true on your "appStore1" store which is associated to the first visible tab list on application startup.

Hope this helps.

slmd
4 Nov 2011, 2:53 AM
Got it! Thx