What is the use of initComponent function in extjs4.1?

mohan picture mohan · Jun 5, 2013 · Viewed 11.6k times · Source

Can anybody tell me what the use of the initComponent function is in extjs4.1? Please provide an example

Thanks

Answer

rixo picture rixo · Jun 5, 2013

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();
}