将自定义xtype小部件呈现到容器

时间:2014-01-15 09:38:13

标签: javascript dom extjs sencha-architect

我从promooted类创建一个自定义xtype小部件。当我想将小部件呈现给容器时,我收到错误Cannot read property 'dom' of null.

cont是我的容器

var d = Ext.widget('MultiViewComponent', {
                renderTo: cont
            });

我试过了renderTo:cont.getLayout()。 我还尝试使用cont.add然后使用cont.doLayout();

对于'renderTo'文档说明: 如果要将Component作为Container的子项,请不要使用此选项。 Container的布局管理器负责呈现和管理其子项。

使用add多次添加时。所有组件都在屏幕上显示,但只有一个在cont.items.items内(最后一个添加)所以当使用cont.removeAll()时,只有一个被删除。

我在这里错过了什么或做错了什么?请帮忙并提出建议。

更新:如果尝试使用container.removeAll()从容器中删除小部件 只删除其中一个小部件。查看container.items.items,即使添加了多个组件,也只有一个。

 var d = Ext.widget('MultiViewComponent', {
            });

            cont.add(d);
            cont.doLayout();

//later 

cont.removeAll();

MultiViewComponent

Ext.define('myApp.view.MultiViewComponent', {
    extend: 'Ext.container.Container',
    alias: 'widget.MultiViewComponent',

    requires: [
        'Ext.form.Label',
        'Ext.grid.Panel',
        'Ext.grid.View',
        'Ext.grid.column.Date',
        'Ext.grid.column.Number'
    ],

    height: 204,
    itemId: 'multiViewComponent',

    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            layout: {
                type: 'vbox',
                align: 'stretch'
            },
            items: [
                {
                    xtype: 'label',
                    itemId: 'multiViewLabel',
                    text: 'My Label'
                },
                {
                    xtype: 'gridpanel',
                    itemId: 'multiViewGrid',
                    width: 498,
                    title: 'My Grid Panel',
                    store: 'Document',
                    columns: [
                        {
                            xtype: 'datecolumn',
                            dataIndex: 'dateCreated',
                            text: 'DateCreated'
                        },
                        {
                            xtype: 'gridcolumn',
                            dataIndex: 'documentType',
                            text: 'DocumentType'
                        },
                        {
                            xtype: 'gridcolumn',
                            dataIndex: 'description',
                            text: 'Description'
                        },
                        {
                            xtype: 'gridcolumn',
                            dataIndex: 'name',
                            text: 'Name'
                        },
                        {
                            xtype: 'gridcolumn',
                            dataIndex: 'creator',
                            text: 'Creator'
                        },
                        {
                            xtype: 'numbercolumn',
                            dataIndex: 'fileId',
                            text: 'FileId'
                        },
                        {
                            xtype: 'numbercolumn',
                            dataIndex: 'metaFileId',
                            text: 'MetaFileId'
                        },
                        {
                            xtype: 'gridcolumn',
                            dataIndex: 'uid',
                            text: 'Uid'
                        }
                    ]
                }
            ]
        });

        me.callParent(arguments);
    }

});

2 个答案:

答案 0 :(得分:2)

cont.itemsExt.util.MixedCollection,不是数组。底层数组位于cont.items.items。无论如何,你不想触摸它。之后使用Ext.container.Container#remove删除您的子组件。

你的文档引用说明了一切......容器用它们的组件做了很多事情,最着名的是渲染,布局和ComponentQuery连线。你不能只是改变他们的DOM元素或javascript成员变量,并期望它们工作。他们必须知道他们的状态变化何时做出相应的反应,这就是为什么你应该总是使用记录的公共方法来操纵它们。让他们知道发生了什么,让他们有机会采取行动。

<强>更新

根据您的反馈意见,您似乎正在使用您的代码做一些时髦的事情。不能说因为你没有发布它...但这里有一个完整的工作示例,说明你想做什么。检查你自己的代码。

Ext.define('My.Component', {
    extend: 'Ext.Component'

    ,alias: 'widget.mycmp'

    ,html: "<p>Lorem ipsum dolor sit amet et cetera...</p>"

    ,initComponent: function() {
        if (this.name) {
            this.html = '<h1>' + this.name + '</h1>' + this.html;
        }
        this.callParent();
    }
});

使用两个初始子项渲染容器:

var ct = Ext.widget('container', {
    renderTo: Ext.getBody()
    ,items: [{
        xtype: 'mycmp'
        ,name: 'First static'
    },{
        xtype: 'mycmp'
        ,name: 'Second static'
    }]
});

在创建后动态添加子项:

// Notice that layout is updated automatically
var first = ct.add({
    xtype: 'mycmp'
    ,name: 'First dynamic'
});

// Possible alternative:
var firstAlt = Ext.widget('mycmp', {
    name: 'First dynamic (alternative)'
});
ct.add(firstAlt);

等等......

var second = ct.add({
    xtype: 'mycmp'
    ,name: 'Second dynamic'
});

通过引用移除给定的孩子:

ct.remove(first);

按索引删除组件:

ct.remove(ct.items.getAt(1));

删除所有组件:

ct.removeAll();

更新2

您的错误是itemId。一个容器不得包含两个具有相同itemId的项目。

答案 1 :(得分:-1)

我不知道您应用的架构,但我认为您可以尝试在某个容器的事件被触发时显示窗口小部件(例如,之前)。