如何在 extjs 中动态添加项目到 window

how to dynamically add items to window in extjs

我想动态添加带有卡片布局的面板,每次关闭 window,我想 destroy window 项目。

第一次打开window,没问题。当我重新打开 window 时,我想创建一个新视图,但实际上它会按如下方式引发 error

This is my window view

Ext.define('MyWebServer.view.qualityassign.CardLayoutWindow', {
    extend: 'Ext.window.Window',
    xtype: 'cardlayoutwindow',

    modal: true,
    closeAction: 'hide',
    closable: true,
    resizable: false,

    layout: 'fit',

    reference: 'cardlayoutwindow',
    controller: 'cardlayoutwindow',

    viewModel: {
        data: {
            initSelectRecordGridStoreDwrParams: []
        }
    },

    width: Ext.Element.getViewportWidth() - 50,
    height: Ext.Element.getViewportHeight() - 64,

    listeners: {
        beforeshow: 'onCardLayoutWindowBeforeShow',
        beforehide: 'onCardLayoutWindowBeforeHide',
        scope: 'controller'
    }
});

This is my window item, a card layout

Ext.define('MyWebServer.view.qualityassign.CardLayoutMain', {
    extend: 'Ext.panel.Panel',
    xtype: 'cardlayoutmain',

    prevBtnText: '« prev',
    nextBtnText: 'next »',

    layout: {
        type: 'card',
        align: 'center',
        deferredRender: true
    },

    bodyPadding: 15,

    defaults: {
        border: false
    },

    viewModel: {
        data: {
            copyRecords: [],
            extractRecord: {},
            planRecord: {},
            allocateRecords: []
        }
    },

    controller: 'cardlayoutmain',
    reference: 'cardlayoutmain',

    initComponent: function() {
        var me = this;

        me.items = me.createItems();

        me.dockedItems = me.createDockedItems();
        me.callParent();


    },

    createItems: function() {
        var mainId = this.id;
        return [{
            itemId: mainId + '-' + 'card-0',
            xtype: 'select-record'
        }, {
            itemId: mainId + '-' + 'card-1',
            xtype: 'extract-strategy'
        }, {
            itemId: mainId + '-' + 'card-2',
            xtype: 'selectqualityplan'
        }, {
            itemId: mainId + '-' + 'card-3',
            xtype: 'allocate-strategy'
        }, {
            id: this.id + '-' + 'card-4',
            html: 'Success'
        }];
    },

    createDockedItems: function() {
        var me = this;
        return [{
            xtype: 'toolbar',
            dock: 'top',
            items: ['->',
                {
                    itemId: 'card-prev',
                    text: me.prevBtnText,
                    handler: 'showPrevious',
                    disabled: true
                },
                {
                    itemId: 'card-next',
                    text: me.nextBtnText,
                    handler: 'showNext'
                }
            ]
        }];
    }
});

This is my window controller

Ext.define('MyWebServer.view.qualityassign.CardLayoutWindowController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.cardlayoutwindow',

    id: 'cardlayoutwindow',

    onCardLayoutWindowBeforeShow: function(view) {

        var newView = this.createNewView();
        Ext.suspendLayouts();
        view.add(newView);
        Ext.resumeLayouts(true);
    },

    createNewView: function() {
        var windowId = this.getView().id;
        var newView = Ext.widget('cardlayoutmain', {
            itemId: windowId + '-' + 'cardlayoutmain' + '-' + Math.floor(Math.random() * 100 + 1),
            reference: 'cardlayoutmain'
        });
        return newView;
    },

    onCardLayoutWindowBeforeHide: function(view) {
        Ext.suspendLayouts();
        view.removeAll(true);
        Ext.resumeLayouts(true);
    }
});

如果您想在 window 关闭时销毁它,只需指定

closeAction : 'destroy'

而不是

closeAction : 'hide'

如果这样做,ExtJS 会破坏并因此完全删除所有项目。此外,如果将 destroy 指定为关闭操作,您将不需要额外的侦听器 (onCardLayoutWindowBeforeHide) 来删除所有项目。如果您再次创建 window,它将从头开始构建(参见 Sencha Fiddle)。

感谢 oberbics 和 Evan Trimboli

我解决了这个问题,只是因为我分配了一个这样的行号:

new Ext.grid.RowNumberer({width: 40}),

然而,当我用 xtype 配置替换它时,它运行良好。

{xtype: 'rownumberer'}

Ext.define('MyWebServer.view.qualityassign.AllocateStrategy',{
    extend  : 'Ext.panel.Panel',
    xtype   : 'allocate-strategy',

    layout  : 'fit',

    requires: [
      'Ext.grid.column.Action',
      'Ext.ProgressBarWidget',
      'Ext.slider.Widget'
    ],

    reference   : 'allocatestrategypanel',
    controller  : 'allocatestrategy',

    viewModel   : {
        data    : {

        }
    },

    listeners   : {
        beforerender    : 'onAllocateStrategyPanelBeforeRender',
        scope           : 'controller'
    },

    header  : {
        xtype   : 'container',
        html    : '<p>Step 4 of 4  Choose allocate strategy</p>'
    },

    initComponent   : function() {
        var me = this;

        me.items = this.createItems();

        me.callParent();
    },

    createItems     : function() {
        var me = this;
        return [{
            xtype       : 'grid',
            reference   : 'allocatestrategygrid',
            frame       : true,
            viewConfig  : {
                loadMask: true
            },

            store       : {
                type    : 'allocate'
            },

            dockedItems :   [{
                xtype   : 'toolbar',
                dock    : 'bottom',
                items   : [{
                xtype   : 'toolbar',
                itemId  : 'allocatestrategygrid-topbar',
                dock    : 'top',
                items   : [{
                    xtype           : 'combo',
                    reference       : 'selectgroupcombo',
                    fieldLabel      : 'qualityinspectorgrp',
                    labelWidth      : 30,
                    editable        : false,
                    triggerAction   : 'all',
                    valueField      : 'sGroupGuid',
                    displayField    : 'sGroupName',
                    forceSelection  : true,
                    store           : {
                        type        : 'selectgroup'
                    },
                    listeners       : {
                        select      : 'onSelectGroupComboSelect',
                        scope       : 'controller'
                    }
                }]
            }],

            columns     : {
                xtype   : 'gridcolumn',
                defaults: {
                    align       : 'center',
                    width       : 100,
                    menuDisabled: true
                },
                items   : [
                     **new Ext.grid.RowNumberer({width: 40}),**
                     {
                         text       : 'agentId',
                         dataIndex  : 'qualInspId'
                     },
                     {
                         text       : 'agentName',
                         dataIndex  : 'qualInspName'
                     },
                     {
                         text       : 'percent',
                         xtype      : 'widgetcolumn',
                         width      : 120,
                         widget     : {
                             bind   : '{record.percent}',
                             xtype  : 'progressbarwidget',
                             textTpl: [
                                 '{percent:number("0")}%'
                             ]
                         }
                     },
                     {
                         text       : '',
                         xtype      : 'widgetcolumn',
                         width      : 120,
                         widget     : {
                             xtype      : 'numberfield',
                             editable   : false,
                             bind       : '{record.percent}',
                             maxValue   : 0.99,
                             minValue   : 0,
                             step       : 0.01,
                             maxLength  : 4,
                             minLength  : 1,
                             autoFitErrors: false
                         }
                     },
                     {
                         text     : '',
                         xtype    : 'widgetcolumn',
                         width    : 120,
                         flex     : 1,
                         widget   : {
                             xtype      : 'sliderwidget',
                             minValue   : 0,
                             maxValue   : 1,
                             bind       : '{record.percent}',
                             publishOnComplete  : false,
                             decimalPrecision   : 2
                         }
                     }
                ]
            }
        }];

    }