Friday 5 April 2013

Custom Component in Extjs : initComponent vs class config


I have struggled while building an app in ExtJS 4, and part of that is confusion on when to configure something in initComponent(),constructor() and at class level configuration. I will recommend to have as much configuration as possible in class config options, because it more readable and is easier to override in subclasses. But make sure we declare all non-primitive types( arrays & objects) in initComponent().
If component we are going to extend is to be created more than once then any non-primitive configs declared as a config option (outside initComponent) will be shared between all instances.
Example :
Ext.define('AM.view.user.List' ,{
    extend: 'Ext.grid.Panel',
    alias : 'widget.userlist',
store: 'Users',
title:'test',
test:new Array("Wind", "Rain", "Fire"),
initComponent: function() {
this.columns = [
            {header: 'Name',  dataIndex: 'name',  flex: 1},
            {header: 'Email', dataIndex: 'email', flex: 1}
        ];
this.callParent(arguments);
    }
});
Now try to creare mulitple instances of above component and change the values of "test array".
var t1 = Ext.create('AM.view.user.List');
var t2 = Ext.create('AM.view.user.List');
t1.test[0]="sdf";

Now try to check the value for "test array" for both the instances, we will find the value has changed for both instances. So as suggested we should declare non-primitive types in initComponent and the above sample code should look like as mentioned below -

Ext.define('AM.view.user.List' ,{
    extend: 'Ext.grid.Panel',
    alias : 'widget.userlist',
store: 'Users',
title:'test',

initComponent: function() {
this.test:new Array("Wind", "Rain", "Fire"),
this.columns = [
            {header: 'Name',  dataIndex: 'name',  flex: 1},
            {header: 'Email', dataIndex: 'email', flex: 1}
        ];
this.callParent(arguments);
    }
});

So when should we use constructor and initComponent? If we are trying to override something from parent class then we should use initComponent, for initilization purpose we should use constructor. Also we need to override initComponent if we want to do anything after the base class initComponent is called (constructor would be too early for this), but before the component is rendered.