正确扩展ExtJS组件而不覆盖侦听器

时间:2013-01-29 17:36:01

标签: javascript extjs extjs4.1

考虑以下示例类Parent

Ext.define('Parent', {

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

};

以及以下类Child扩展默认Parent

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

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

即使Child未指定render的侦听器(它仅提供afterrenderrender侦听器(在Parent类中定义)在Child的组件渲染时不再被触发;即新的侦听器规范将侦听器覆盖

如何解决这个问题?

4 个答案:

答案 0 :(得分:12)

您可以在initComponent中指定处理程序,而不是使用listeners配置对象。

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

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

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

listeners配置方法不起作用的原因是because the config object that is passed to Ext.define gets Ext.apply'd到创建的任何新对象。换句话说,它完全覆盖任何引用类型(例如listeners对象)。

首选使用initComponent,因为它专门设计用于子类化。

答案 1 :(得分:3)

嗯,目前框架中没有干净的解决方案;然而,像这样的一些kludgy可以使用相对安全:

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

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

我必须承认它并不比使用initComponent好多少,但至少它更具说明性。

答案 2 :(得分:2)

通过使用initComponenton内声明事件处理程序来解决“已修复”问题。所以子类的示例代码是:

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

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

对我来说看起来并不好看;如果有人有更好的解决方案,请回答这个问题。

答案 3 :(得分:0)

在版本6.02中,在子视图中使用新方法配置viewConfig时,仍会在viewConfig中保留其他方法。真的很好。