在initComponent中动态创建和添加组件

时间:2013-08-21 11:46:19

标签: extjs extjs4.2

我有一个动态配置项目的视图。这些子项也动态配置。

我正在尝试使用initComponent,但是在下面的代码中,childItem上最小的initComponent存在导致错误(“无法读取未定义的属性'长度')。

在childItem上没有initComponent,其余的工作。

这有什么问题?有替代方法吗?

Ext.define('myapp.view.MyView', {
    extend: 'Ext.container.Container',

    initComponent: function () {
        var me = this;

        var childItem = {
            xtype: 'container',

            initComponent: function () {
                var me = this;
                // I want the childItem to do some configuration here.
                me.callParent();
            }
        };

        me.items = [
            childItem
        ];

        me.callParent();
    }
});

3 个答案:

答案 0 :(得分:3)

您可以将未记录的xhooks配置用于组件。请参阅this

Ext.ComponentManager.create({
    xtype: 'panel',
    xhooks: {
        initComponent: function() {
            console.log('in local override for this specific instance of panel');
            this.items = [{
                xtype: 'panel',
                xhooks: {
                    initComponent: function() {
                        console.log('in local override for this specific instance of panel');
                        this.items = [{html: 'hi'}];
                        this.callParent();
                    }
                }
            }];
            this.callParent();
        }
    }
}, 'panel');

在组件创建过程中,当Ext看到xhooks属性时,它会使用xhooks config中包含的匹配函数覆盖当前实例的函数。这可以确保callParent有效。

答案 1 :(得分:1)

您没有在代码中正确扩展Ext.Container。如果您要覆盖initComponent,请先使用Ext.define定义您的课程:

Ext.define('MyContainer', {
    extend: 'Ext.Container',
    alias: 'widget.my-ct',

    initComponent: function () {
        var me2 = this;
        // I want the childItem to do some configuration here.
        me2.callParent();
    }
});

Ext.define('myapp.view.MyView', {
    extend: 'Ext.container.Container',

    initComponent: function () {
        var me = this;

        var childItem = {
            xtype: 'my-ct'
        };

        me.items = [
            childItem
        ];

        me.callParent();
    }
});

编辑:

作为最佳实践,您应始终在单独的文件中定义类。我认为这是常识,只是想解释为什么你的原始代码出错,但评论部分抱怨所以我改变了这个以使用更合适的代码。

答案 2 :(得分:0)

callParent仅适用于已通过Ext.define(或等效近似值)传递的方法。在这里,你正在进行“运行时”覆盖,因此callParent对儿童不起作用。

您最熟悉的下一个开发人员选项是将这些转换为合法的Ext覆盖。为简单起见,您可以使用匿名类。例如:

var childClass = Ext.define(null, {
    extend: 'Ext.container.Container'

    ,initComponent: function() {

        // Here that will work
        this.callParent(arguments);
    }
});

var childItem = new childClass;

// ...

另一个选择是通过在正确的范围内调用父方法来自己完成callParent的工作。这里的问题是你必须知道如何访问父方法,但是这个选项很适合吹嘘你的javascript技能,因为它会导致一些野蛮语法大多数(非javascript)开发人员无法弄清楚;)在您的情况下,请将您孩子的this.callParent()替换为:

Ext.container.Container.prototype.initComponent.apply(this, arguments);

在这两种情况下,请不要忘记您必须要求Ext.container.Container。在第一种情况下,这将确保代码同步运行,在第二种情况下,它将避免它在未定义的类上崩溃。