Can anybody tell me what the use of the initComponent
function is in extjs4.1? Please provide an example
Thanks
This method is akin to a constructor
for components. It is called by the true constructor
, and is a really good hook point to customize the initialization of the component (as said in the name!).
Except in some very rare occasions, you should override initComponent
instead of the constructor
because the more basic initialization will already have taken place. Most notably, the config object passed to the constructor will have already been merged into the object.
Let's say you want to customize the configuration of a component, like setting its width
. If you try to do that in the constructor, you'll have to check first whether we've been passed a config object or not (to avoid trying to set a property on undefined
), and you'll have the override the config object which is bad practice. If you set the option in this
, that may get overridden by the config object. If you change the value in config object, you modify the object, breaking expectations from the calling code (i.e. reusing the config object will have unexpected result). In initComponent
, the value will always be this.width
, you don't have to worry about the config.
Another interesting point is that initComponent
is the place where child components (for container), stores, view, templates, etc., are created. So, before calling the superclass initComponent
method, you can act on these being sure they've not already been used or needed (e.g. adding items, creating the store, etc.). On the other hand, once you've called the super method, you are guaranteed that all this dependencies have been created and instantiated. So that's the good place to add listeners to dependencies, for example.
That being said, keep in mind that no rendering is taking place in initComponent
. Child components are created and configured, but their DOM elements have not been created. To affect the rendering, you'll have to use rendering related events or look for the afterRender
or onRender
methods...
Here's an illustrated summary:
constructor: function(config) {
// --- Accessing a config option is very complicated ---
// unsafe: this may be changed by the passed config
if (this.enableSomeFeature) { ... }
// instead, you would have to do:
var featureEnabled;
if (config) { // not sure we've been passed a config object
if (Ext.isDefined(config.featureEnabled)) {
featureEnabled = config.featureEnabled;
} else {
featureEnabled = this.enableSomeFeature;
}
} else {
featureEnabled = this.enableSomeFeature;
}
// now we know, but that wasn't smooth
if (featureEnabled) {
...
}
// --- Even worse: trying to change the value of the option ---
// unsafe: we may not have a config object
config.enableSomeFeature = false;
// unsafe: we are modifying the original config object
(config = config || {}).enableSomeFeature = false;
// cloning the config object is safe, but that's ineficient
// and inelegant
config = Ext.apply({enableSomeFeature: false}, config);
// --- Super method ---
this.callParent(arguments); // don't forget the arguments here!
// --------------------
// here initComponent will have been called
}
,initComponent: function() {
// --- Accessing config options is easy ---
// reading
if (this.enableSomeFeature) { ... }
// or writing: we now we change it in the right place, and
// we know it has not been used yet
this.deferRender = true;
// --- Completing or changing dependant objects is safe ---
// items, stores, templates, etc.
// Safe:
// 1. you can be sure that the store has not already been used
// 2. you can be sure that the config object will be instantiated
// in the super method
this.store = {
type: 'json'
...
};
// --- However that's too early to use dependant objects ---
// Unsafe: you've no certitude that the template object has
// already been created
this.tpl.compile();
// --- Super method ---
this.callParent();
// --------------------
// Safe: the store has been instantiated here
this.getStore().on({
...
});
// will crash, the element has not been created yet
this.el.getWidth();
}