1

Disclaimer: I am relatively new to ExtJS (version 5.01). I am hoping to reach some ExtJS experts to point me in the right direction: I am getting an error when specifying an initComponent method within an items config. The code below generates the error:

"Uncaught TypeError: Cannot read property 'items' of undefined"

The error disappears when the 'initComponent' function of the north-child panel is commented out. I have the feeling I missed something on initialization order.

Q: How can I specify an initComponent method of a child item within the items configuration?

Ext.define('MyApp.view.TestView', {
    extend: 'Ext.panel.Panel',
    title: 'Parent',
    height: 300,
    layout: 'border',

    items: [{
        xtype: 'panel',
        region: 'north',
        title: 'North Child',

        /* Problematic function: If commented, it works */
        initComponent: function(){
            console.log("test north child");
            this.callParent(arguments);
        }
    }],


    initComponent: function(){

        console.log("Test parent");
        this.callParent(arguments);
    }
});
user1362700
  • 155
  • 8
  • You cannot do it this way! Have a look at [this question](http://stackoverflow.com/questions/14254321/best-practice-for-overriding-classes-properties-in-extjs/14254627#14254627) a further information on overriding. Your problem is, that the scope of the function will be the scope of the 'MyApp.view.TestView' instance. – sra Sep 02 '14 at 05:58
  • Is there an ExtJS way of attaching a context, i.e. the object that is generated from the config, to the function? Something along the lines of a function wrapper with a scope config? – user1362700 Sep 02 '14 at 06:17
  • Please tell us why exactly you want to use a initComponent function on the child. Most of the time, it is not necessary. – Alexander Sep 02 '14 at 07:16

1 Answers1

1

Short answer: You can't define initComponent on a child, because you can't do anything there that can't be done anywhere else.

InitComponent is executed when an instance of the component 'MyApp.view.TestView' is created (you only defined it here, using Ext.define). It can be created using Ext.create('MyApp.view.TestView',{, or by creating another view that has this component added as an item, or by deriving another component (extend:'MyApp.view.TestView').

All the child components are also created when 'MyApp.view.TestView' is created, so the initComponent function on the child would be superfluous, because the child cannot be created without the parent, so the initComponent of the parent can be used for everything that you want to do in the child's initComponent.

If you need sth. to be calculated before the items can be addded, you would proceed as follows:

Ext.define('MyApp.view.TestView', {
    extend: 'Ext.panel.Panel',
    title: 'Parent',
    height: 300,
    layout: 'border',

    initComponent: function(){
        var me = this,
            tf = Ext.getCmp("someTextField"),
            myTitle = (tf?tf.getValue():'');
        Ext.applyIf(me,{
            items: [{
                xtype: 'panel',
                region: 'north',
                title: myTitle,
            }]
        });
        this.callParent(arguments);
    }
});

Please refer to the docs what exactly Ext.applyIf does (and how it differs from Ext.apply, because that function also comes handy sometimes).

Alexander
  • 19,906
  • 19
  • 75
  • 162
  • Thanks. That helped! For some reason I assumed that child configs are implicitly wrapped in an anonymous class definition, similar to the configuration object of Ext.define() function. – user1362700 Sep 02 '14 at 07:41