开发者

ExtJS: Best way to destroy card when hidden, instantiate when shown?

I'm using a CardLayout to switch between full-screen panels that have several nodes. To minimize memory usage, I want to destroy a card when it is hidden and only re-create it (from a config object) if/when it is shown.

If you look at the 'Switch Cards' button handler below, you'll see how I'm currently accomplishing this. It seems clumsy, however (using ComponentMgr to instantiate the card, adding it to the container, removing the old card, etc.). Is there a better way to accomplish this? Again, my main goal is to destroy the card when it's not visible.

Thanks!

var panel1Cfg = {
    id: 'card-1',
    xtype: 'panel',
    html: 'Card 1',
    listeners: {
        render: function() { console.log('render card 1'); },
        beforedestroy: function() { console.log('destroying card 1'); }
    }
};

var panel2Cfg = {
    id: 'card-2',
    xtype: 'panel',
    html: 'Card 2',
    listeners: {
        render: function() { console.log('render card 2'); },
        beforedestroy: function() { console.log('destroying card 2'); }
    }
};

var cardPanel = new Ext.Panel({
    renderTo: document.body,
    layout: 'card',
    items: [ panel1Cfg ],
    activeItem: 0,
    itemCfgArr: [ panel1Cfg, panel2Cfg ],
    activeItemCfgIndex: 0,
    tbar: [
        {
            text: 'Switch Cards',
            handler: function() {
                var cardToRemove = cardPanel.getLayout().activeItem;

                // Figure out which panel create/add/show next
                cardPanel.activeItemCfgIndex = (cardPanel.activeItemCfgIndex + 1) % cardPanel.itemCfgArr.length;

                // Use cfg to create component and then add
                var cardToShow = Ext.ComponentMgr.create(cardPanel.itemCfgArr[cardPanel.activeItemCfgIndex]);
                cardPanel.add(cardToShow);

      开发者_开发知识库          // Switch to the card we just added
                cardPanel.getLayout().setActiveItem(1);

                // Remove the old card (console should show 'destroy' log msg)
                cardPanel.remove(cardToRemove);
            }
        }
    ]
});


I think a more elegant solution would be to create a class that wraps your config, and handles the creating/destroying when it is activated/deactivated. This way you Card layout doesn't need to know about this special handling, and you could potentially mix cards that get destroyed and cards that don't. You could also reuse this behavior in other layouts, such as a TabPanel, or even AccordianLayout.

Your class might look something like this:

CleanPanel = Ext.extend(Ext.Panel, {

    /** @cfg panelCfg - configuration for wrapped panel */
    panelCfg: null,

    layout: 'fit',
    autoDestroy: true,

    initComponent: function() {
        CleanPanel.superclass.initComponent.call(this);

        this.on({
            scope: this,
            activate: this.createPanel,
            deactivate: this.destroyPanel
        });
    },

    createPanel: function() {
        this.add(this.panelCfg);
    },

    destroyPanel: function() {
        this.removeAll();
    }

});

Add a couple of these to your main Panel, wrapping your panel1Cfg and panel2Cfg, keep your activeItem switching logic in the main panel, and it should work quite nicely. There may be some initialization details to work out, but you get the idea.

Good luck!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜