ExtJS中具有边框布局的复合组件

ExtJS中具有边框布局的复合组件,extjs,extjs4,Extjs,Extjs4,我想知道我应该如何开始制作一个定制的复合组件。有边框布局但其项目显示在边框布局的中心区域的一种。下图显示了我试图实现的目标: 在伪代码中,这将是: Ext.define('App.custom.ContentView', { extend: 'Ext.container.Container', xtype: 'contentview', layout: 'border', northCmp: ..., // Custom north region compone

我想知道我应该如何开始制作一个定制的复合组件。有边框布局但其项目显示在边框布局的中心区域的一种。下图显示了我试图实现的目标:

在伪代码中,这将是:

Ext.define('App.custom.ContentView', {
    extend: 'Ext.container.Container',
    xtype: 'contentview',
    layout: 'border',
    northCmp: ..., // Custom north region component.
    westCmp: ..., // Custom west region component.
    centerCmp: ..., // Placeholder for the items it will have.
    items: [] // Filled in by each implementation, shown in the center region.
});


Ext.create('App.custom.ContentView', {
    layout: 'vbox', // Applies to center region of 'contentview'.
    items: [
        // Items that go into the center region of the 'contentview'.
    ]
});
我浏览了ExtJS源代码,并查看了Sencha市场上的几个示例;但我没有发现一个明显的例子不包含大量重复代码


我们将非常感谢您的任何帮助或朝着正确的方向轻推!)

你不应该那样做。请不要让我被误解,您的意图是好的,但您描述的实现将在将来的某个时候掌握。我知道,因为我在Ext初次亮相时也做了类似的事情。根据您的口味/需求/任何看似令人愉快的简化,调整组件声明的想法。。。不幸的是,在实践中,您想要做的是为现有结构赋予另一种意义
在您的例子中是items
)。以下是它真正带给您的:

  • 应用程序外部的所有代码(包括Ext和Ext的未来版本!)都希望组件/容器以经典方式运行。也就是说,容器的项实际上是它包含的项,而不是它的子项。意外的行为是意料之中的

  • 您将不可避免地希望以某种方式自定义此组件。您已经开始使用中心区域的布局。如果重写组件的工作方式,则必须为要使用的任何功能编写某种配置代理。大负担而不是一点点储蓄。不值得

  • 最后,过一段时间你就会忘记你对这个组件所做的一切。你必须调试你的代码,只是为了理解它应该做什么(也就是说,在调试真正的问题之前)

很抱歉给你讲课。。。尽管如此,这并不意味着没有一种方法可以接近你想要的,而不成为重新构建框架的牺牲品

我会这样做():


感谢您的优秀反馈!我知道现在弊大于利,我错误地认为使用现有的框架/配置会更省力。:)回答得很好。
Ext.define('My.custom.BorderContainer', {
    extend: 'Ext.container.Container'

    // xtype is used in Ext3 and Touch... Ext4 uses aliases
    ,alias: 'widget.contentview'

    ,layout: 'border'
    ,items: [{
        region: 'north'
        ,xtype: 'container'
        ,html: "<h1>Some header</h1>"
        ,style: 'background-color: lightblue;'
    },{
        region: 'west'
        ,xtype: 'container'
        ,split: true
        ,html: "<h1>Some menu</h1>"
        ,style: 'background-color: purple;'
    },{
        region: 'center'
        ,xtype: 'container'
    }]

    /**
     * Configuration of the center panel.
     *
     * @cfg {Object/Ext.Component}
     */
    ,center: null

    ,initComponent: function() {
        var center = this.center;
        if (center) {
            if (center instanceof Ext.Component) {
                center.region = 'center';
            } else {
                // never modify a passed config object, that could
                // break the expectations of the using code
                center = Ext.clone(center);
                // apply default config, including the region
                center = Ext.applyIf(center, this.items[2]);
            }
            this.items[2] = center;
        }
        // else use default config, already in place

        this.callParent(arguments);
    }
});
Ext.widget('contentview', {
    renderTo: Ext.getBody()
    ,height: 300
    ,center: {
        layout: {
            type: 'vbox'
            ,align: 'center'
        }
        ,defaults: {
            xtype: 'component'
            ,margin: 10
            ,padding: 10
        }
        ,items: [{
            html: 'Red'
            ,style: 'background-color: green;'
        },{
            html: 'Green'
            ,style: 'background-color: blue;'
        },{
            html: 'Blue'
            ,style: 'background-color: red;'
        }]
    }
});

Ext.widget('contentview', {
    renderTo: Ext.getBody()
    ,height: 300
    ,center: {
        xtype: 'tabpanel'
        ,tabPosition: 'bottom'
        ,items: [{
            title: 'First Tab'
            ,html: "I'm empty!"
        },{
            title: 'Second Tab'
        }]
    }
});

Ext.widget('contentview', {
    renderTo: Ext.getBody()
    ,height: 300
    // passing a component instance instead of a config object
    ,center: Ext.widget('button', {
        text: "Foo"
    })
});