Greg Lafrance
Greg Lafrance

Reputation: 809

How do I dynamically add items to ExtJS 4.2.1 border layout region containers?

I am creating a reusable generic view, which is a container with border layout and empty north, west, and center containers.

I want to use this generic view, and dynamically define items for the north, west, and center containers.

As seen below, I am trying to do this via a custom config, and auto-generated "apply" functions.

But nothing is displaying in the UI.

What might I be doing wrong here?

I'm getting this error:

TypeError: items is undefined len = items.length,

Thanks in advance.

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>APP</title>
    <link rel="stylesheet" type="text/css" href="../../ext-4.2.1.883/resources/css/ext-all.css">
    <script type="text/javascript" src="../../ext-4.2.1.883/ext-all-debug.js"></script>
    <script src="app.js"></script>
</head>
<body></body>
</html>

Ext.Loader.setConfig({
    enabled: true
});

Ext.application({

    name: 'APP',
    appFolder: '../simplemvcBorderLayout',
    autoCreateViewport: true
});

Ext.define('APP.view.Viewport', {
    extend: 'Ext.container.Viewport',
    alias: 'widget.appviewport',

    autoScroll: true,
    layout: 'fit',

    requires: [
        'view.Main'
    ],

    items: [{
        xtype: 'mainAppView',
        northItems: [{
            xtype: 'label',
            text: 'here'
        }],
        westItems: [{
            xtype: 'label',
            text: 'here'
        }],
        centerItems: [{
            xtype: 'label',
            text: 'here'
        }]
     }]
});

Ext.define('APP.view.Main', {
    extend: 'Ext.container.Container',
    alias: 'widget.mainAppView',

    autoScroll: true,
    layout: 'border',

    config: {
        northItems: null,
        westItems: null,
        centerItems: null
    },

    constructor: function(config) {
        this.initConfig(config);
        this.callParent(arguments);
    },

    applyNorthItems: function(northItems) {
        this.northItems = northItems;
        this.doLayout();
    },
    applyWestItems: function(westItems) {
        this.westItems = westItems;
        this.doLayout();
    },
    applyCenterItems: function(centerItems) {
        this.centerItems = centerItems;
        this.doLayout();
    },

    items: [
        {
            xtype: 'container',
            itemId: 'appHeaderContainer',
            region: 'north',
            height: 60,
            items: this.northItems
        },
        {
            xtype: 'container',
            itemId: 'appNavigationContainer',
            region: 'west',
            width: 85,
            items: this.westItems
        },
        {
            xtype: 'container',
            itemId: 'appContentContainer',
            region: 'center',
            items: this.centerItems
        }
    ]
});

Upvotes: 2

Views: 6860

Answers (1)

Benjamin E.
Benjamin E.

Reputation: 5172

Your code only adds references to objects, that's why nothing happens. In Ext.js you add items to containers by calling .add() on the parent. See here.

Basically you need to get the initial container for the region you want to add children and then call add() or remove() etc.

Items within containers that have been created are Mixed Collections, not just arrays of config objects.

Update

Here is a better way to do it (not tested though). First of all I would not use the config property to hold initial item configs. Initial configs can be on the class prototype (not necessary) or just added when the class is created (just document it in your code somehow). When adding child components to regions, they can always be created by their xtype. The .add() method takes a config object or a created component. Either way is fine.

Ext.define('APP.view.Main', {
    extend: 'Ext.container.Container',
    alias: 'widget.mainAppView',

    layout: 'border',

    northItems: null,

    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            items: [
                {
                    xtype: 'container',
                    itemId: 'appHeaderContainer',
                    region: 'north',
                    height: 60,
                    items: me.northItems
                }
            ]
        });

        me.callParent(arguments);
    },

    applyNorthItems: function(northItems) {
        this.down('#appHeaderContainer').add(northItems);
    }
});

Upvotes: 2

Related Questions