10

Consider the following example class Parent:

Ext.define('Parent', {

    ...
    listeners: {
        render: {
            fn: doSomething
        },
    },

};

and the following class Child extending default Parent above:

Ext.define('Child', {
    extend: 'Parent',

    ...
    listeners: {
        afterrender: {
            fn: doSomething
        },
    },
};

Even though Child does not specify a listener for render (it only provides for afterrender) the render listener (defined in the Parent class) is not fired anymore upon Child's component rendering; i.e. the listener is overwritten by the new listeners specification.

How to fix this?

Joseph Victor Zammit
  • 14,760
  • 10
  • 76
  • 102

4 Answers4

13

You can specify the handler in initComponent, instead of using the listeners config object.

Ext.define('Child', {
    extend: 'Parent',

    ...
    initComponent: function() {
        this.on('afterrender', this.onAfterRender);
    },

    onAfterRender: function() {
        ...
    }
};

The reason that the listeners config method doesn't work is because the config object that is passed to Ext.define gets Ext.apply'd to any new objects that are created. In other words, it completely overwrites any reference types (e.g. the listeners object).

Using initComponent is preferred, since it's specifically designed to be overridden for subclassing.

voithos
  • 68,482
  • 12
  • 101
  • 116
3

Well, there is no clean solution in the framework at the moment; however something a bit kludgy like this can be used relatively safe:

Ext.define('Child', {
    extend: 'Parent',

    listeners: Ext.merge(Parent.prototype.listeners || {}, {
        ...
    })
});

I must admit that it's not much better than using initComponent but at least it's a bit more declarative.

Alex Tokarev
  • 4,821
  • 1
  • 20
  • 30
2

"Fixed" issue by declaring the event handler within initComponent using on. So the sample code for the child class would be:

Ext.define('Child', {
    extend: 'Parent',

    ...
    initComponent : function(args) {
        var me = this;
        me.callParent(args);
        me.on('afterrender', me.doSomething, this);
    },
};

Still doesn't look that nice to me; if anyone has a better solution, please answer the question.

Joseph Victor Zammit
  • 14,760
  • 10
  • 76
  • 102
  • Actually, I believe that is the preferred method. `initComponent` is specifically made for this purpose. There's only so much you can do with config objects... – voithos Jan 29 '13 at 18:12
0

In version 6.02 configuring viewConfig with a new method in a child, will still keep other methods within viewConfig from the parent. Really good.