PDA

View Full Version : [PR 1] initComponent replacement -> initialize



tobiu
12 Oct 2011, 12:42 PM
hi team,

i am not 100% sure this is a bug, but definitely not working the ways i try it.

the first version is fine:


Ext.define('SC.view.login.Login', {
extend : 'Ext.form.Panel',
alias : 'widget.login',

config : {
scrollable : 'vertical',
items : [{
xtype : 'fieldset',
title : 'Enter Login Data:',
items : [{
xtype : 'emailfield',
label : 'Email',
name : 'email'
}]
}]
}
});


when i want to use initialize it throws an error:


Ext.define('SC.view.login.Login', {
extend : 'Ext.form.Panel',
alias : 'widget.login',

config : {
scrollable : 'vertical'
},

initialize : function() {
Ext.apply(this, {
items : [{
xtype : 'fieldset',
title : 'Enter Login Data:',
items : [{
xtype : 'emailfield',
label : 'Email',
name : 'email'
}]
}]
});

this.callParent();
}
});


Uncaught TypeError: Cannot read property 'length' of undefined
Ext.define.setRenderedsencha-touch-all-debug.js:40710
Ext.define.onAddsencha-touch-all-debug.js:40589
Ext.define.doAddsencha-touch-all-debug.js:40357
Ext.define.addsencha-touch-all-debug.js:40335
Base.implement.callParentsencha-touch-all-debug.js:2768
override.addsencha-touch-all-debug.js:40844
Ext.define.initMain.js:32
Ext.define.onBeforeLaunchsencha-touch-all-debug.js:29560
Ext.apply.onDocumentReadysencha-touch-all-debug.js:5729
Ext.apply.onReady.fnsencha-touch-all-debug.js:4897
Ext.apply.triggerReadysencha-touch-all-debug.js:4878
(anonymous function)sencha-touch-all-debug.js:1976
Ext.apply.requiresencha-touch-all-debug.js:4725
Ext.apply.triggerReadysencha-touch-all-debug.js:4872
Ext.apply.refreshQueuesencha-touch-all-debug.js:4447
Ext.apply.refreshQueuesencha-touch-all-debug.js:4479
Ext.apply.refreshQueuesencha-touch-all-debug.js:4479
Ext.apply.onFileLoadedsencha-touch-all-debug.js:4794
(anonymous function)sencha-touch-all-debug.js:1976
Ext.apply.injectScriptElement.onLoadFn

TommyMaintz
12 Oct 2011, 1:14 PM
This is not what initialize is meant for. In ST2 every component has its DOM available at all times (even if its not rendered yet). Initialize is a method you can use to set up DOM / Component listeners, add classes to elements and other things like that. Also, the traditional Ext.apply(this, {config}); is not how you do things. Instead you are meant to use getters and setters. In this case you would want to do this.setItems(); However, much easier for your example would be to do the following:



Ext.define('SC.view.login.Login', {
extend : 'Ext.form.Panel',
alias : 'widget.login',

config : {
scrollable : 'vertical',
items: [{
xtype : 'fieldset',
title : 'Enter Login Data:',
items : [{
xtype : 'emailfield',
label : 'Email',
name : 'email'
}]
}]
}
});


Config gets deeply merged in ST2 (note that items arrays do not yet get merged), so you can put deeply nested configuration in it. Check out the kitchensink views for more details.

Mainly it comes down to the fact that initComponent is never needed anymore. Check out the source code for the widgets in our framework to see what I mean by that. None of our widgets uses initComponent, instead you define configs and create update/apply methods for them. This way any configuration can always be changed dynamically, even after component instantiation/rendering.

mitchellsimoens
12 Oct 2011, 1:29 PM
There will be more clarification on many points as all the things we are doing are new. If you try to use initComponent, there is a console log that says to use initialize instead. I know when I first tried, I assumed it would work the same but ran into the same problem. Just have to get used to the new ST2 way of doing things.

tobiu
12 Oct 2011, 2:04 PM
@Tommy: your example is exactly the same as my first version :)

BUT, and this is a huge problem for me, this exampe was just meant as a super short demo. in general i used initComponent a lot to do custom logic like dynamically generating the items and then add them via Ext.apply. i will try out using the setters. i hope this is possible in the initialize, maybe after the parent call? i will post my results.

tobiu
12 Oct 2011, 2:10 PM
ok,



Ext.define('SC.view.login.Login', {
extend : 'Ext.form.Panel',
alias : 'widget.login',

config : {
scrollable : 'vertical'
},

initialize : function() {
this.callParent();

this.setItems([{
xtype : 'fieldset',
title : 'Enter Login Data:',
items : [{
xtype : 'emailfield',
label : 'Email',
name : 'email'
}]
}]);

}
});


does work. i hope this is the meant way to go ;)

TommyMaintz
12 Oct 2011, 2:14 PM
Yes, that looks much better. Couple things of note, it does not matter if you put things before or after the callParent in that specific method (unlike before with initComponent). Also, I would use this.add (or this.insert) as it won't override any items already in the container.

tobiu
12 Oct 2011, 2:37 PM
makes sense.

Grgur told me to take a closer look at Ext.factory().

I just started and it should definitely find its way into the API docs soon ;)

Sabareesh
15 Feb 2012, 4:30 AM
I have the following code of defining a componenet in .js file

Ext.define('pieChartPanel', {
extend : 'Ext.Panel',
alias : 'widget.piechartpanel',


config : {
scrollable : 'vertical'
},


initialize : function() {
this.callParent();


this.setItems([{
xtype : 'toolbar',
id:'fs',
title : 'chartPanel',
items : [{
xtype : 'button',
text :'Back',
handler: function(){
alert("hi");
}
}]
}]);


}
});



How do i call this component in my main app.js file where i have the launch() function .

I am using the following code to add this component in a panel . I dont know whether i am doing the correct thing or not


Ext.getCmp('charts').add(pieChartPanel);

where 'charts' is my panel id ..

Please guide me
Thanks in advance..

mitchellsimoens
15 Feb 2012, 4:33 AM
For simplicity yes you can do that. I personally do not like the usage of id.

Sabareesh
15 Feb 2012, 4:43 AM
Thanks mitchell . But that was not working for me .
I have list in the 'chart' panel on click on the list im hiding that list and wanted the new componenet to be shown in the panel which is 'pieChartPanel' that i am defining . The hiding works fine but the new componenet is not added . I do know why . this is the thing im using .

select: function (view, record) {
if (record.get('name') === 'Run Rate') {

//Ext.Msg.alert('Selected!', 'You selected ' + record.get('name'));
Ext.getCmp('lst').hide();
Ext.getCmp('charts').add(pieChartPanel);
}
},

mitchellsimoens
15 Feb 2012, 4:46 AM
You're not giving enough information. What is 'charts'? What is 'lst'? What layouts are then?

Sabareesh
15 Feb 2012, 4:51 AM
This is my app.js file


Ext.application({
// Setup your startup screens for tablets and phones and assign the icon
tabletStartupScreen: 'resources/images/tablet_startup.png',
phoneStartupScreen: 'resources/images/phone_startup.png',
icon: 'resources/images/icon.png',
glossOnIcon: false,


// Require all the components used for this example
requires: [
'Ext.SegmentedButton',
'Ext.Toolbar'
],
launch: function() {
Ext.Viewport.add({
xtype: 'tabpanel',
id : 'mobileTab',
fullScreen : true,
items:[
{
title: 'Home',
hidden:true,
iconCls: 'home',
cls: 'home',
html: [
'<img width="65%" src="../assets/images/dashboardlogo.png" />',
'<h1>Welcome to M2 Report Mobile</h1>'
].join("")
},
{
xtype: 'panel',
title: 'Charts',
id: 'charts',
iconCls: 'star',
layout: 'card',
items: [
{
xtype: 'list',
id : 'lst',
itemTpl: '{name}',
listeners: {
select: function (view, record) {
if (record.get('name') === 'Pie Chart') {

//Ext.Msg.alert('Selected!', 'You selected ' + record.get('name'));
Ext.getCmp('lst').hide();
Ext.getCmp('charts').add(pieChartPanel);

}
},
store: {
fields: ['title', 'name'],
data: [
{
title: 'Run Rate',
name: 'Run Rate'
},
{
title: 'Revenue Sales',
name: 'Revenue Sales'
},
{
title: 'Pie Chart',
name: 'Pie Chart'
}
]
}
}]
}
]
});
},



});





this is my pieChart.js file


Ext.define('pieChartPanel', {
extend : 'Ext.Panel',
alias : 'widget.piechartpanel',


config : {
scrollable : 'vertical'
},


initialize : function() {
this.callParent();


this.setItems([{
xtype : 'toolbar',
id:'fs',
title : 'chartPanel',
items : [{
xtype : 'button',
text :'Back',
handler: function(){
alert("hi");
}
}]
}]);


}
});

The problem is i am not sure of how to use this defined componenet in my app.js file

mitchellsimoens
15 Feb 2012, 4:53 AM
So 'charts' is a card layout. In that case, you need to use setActiveItem on that panel to switch to a new component, you don't need to do hide() on the 'lst' list.

Sabareesh
15 Feb 2012, 5:01 AM
Thanks mitchell

Im still not getting how this defined component can be used in my app.js file
In the chart panel initially i have only the list .
How to add this defined component in my chart panel.

mitchellsimoens
15 Feb 2012, 5:14 AM
Ext.getCmp('charts').setActiveItem({
xtype : 'piechartpanel'
});

That will create an instance using the xtype of piechartpanel, add that instance to the charts component and set it as the active item.

Sabareesh
15 Feb 2012, 5:29 AM
Thanks mitchell

That worked fine .

U r great..

Sabareesh
16 Feb 2012, 5:24 AM
Hi mitchell

I have defined a component in a seperate file and used it in my file as u told me .
Everything is working fine except for the component is appearing in the left side of the screen even though i mentioned "fullscreen:true".

Sabareesh
16 Feb 2012, 5:56 AM
Sorry , it was cache problem .Its working fine