【问题标题】:Composite component with a border layout in ExtJSExtJS 中带有边框布局的复合组件
【发布时间】:2014-02-07 09:13:35
【问题描述】:

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

在伪代码中是:

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 Market 上查看了几个示例;但是我还没有找到一个不包含大量重复代码的明显示例。

任何帮助,或朝着正确的方向轻推,将不胜感激! :)

【问题讨论】:

    标签: extjs extjs4


    【解决方案1】:

    你不应该那样做。请不要让我被误解,你的意图是好的,但你描述的实现将在未来的某个时候抓住。我知道是因为我在 Ext 出道时做过类似的事情。将组件声明调整为符合您的口味/需要/任何可能看起来令人愉快的简化的想法......不幸的是,在实践中您想要做的是为现有构造赋予另一种含义(@ 987654322@ 在您的情况下)。以下是它真正为您带来的:

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

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

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

    抱歉讲课...话虽如此,但这并不意味着没有办法接近你想要的,而不会成为重构框架的牺牲品。

    我会这样做 (fiddle):

    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);
        }
    });
    

    请注意我是如何添加一个 center 配置选项而不是尝试回收现有选项(itemslayout 等)。这使我可以将任何我想要的、定制的、使用通常语法的放在其中。未来的我和同事可能会为此送我巧克力!例如:

    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"
        })
    });
    

    【讨论】:

    • 感谢您的出色反馈!我知道现在弊大于利,我有一个误解,那就是使用现有的框架/配置会更省力。 :) 绝妙的答案。
    猜你喜欢
    • 1970-01-01
    • 2013-11-24
    • 2014-08-12
    • 2012-02-24
    • 2011-07-30
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    相关资源
    最近更新 更多