似乎ViewModel的视图在extjs中被销毁后仍然存在

似乎ViewModel的视图在extjs中被销毁后仍然存在,extjs,mvvm,extjs6,Extjs,Mvvm,Extjs6,我肯定我在这里遗漏了一些东西,但我就是看不到它是什么 我有一个用ExtJS6构建的演示项目。在里面我有一个库存物品的网格 Ext.define("InventoryDemo.view.inventory.list.Inventory",{ extend: "Ext.container.Container", xtype: 'inventory', requires: [ "InventoryDemo.view.inventory.list.Invento

我肯定我在这里遗漏了一些东西,但我就是看不到它是什么

我有一个用ExtJS6构建的演示项目。在里面我有一个库存物品的网格

Ext.define("InventoryDemo.view.inventory.list.Inventory",{
    extend: "Ext.container.Container",
    xtype: 'inventory',

    requires: [
        "InventoryDemo.view.inventory.list.InventoryController",
        "InventoryDemo.view.inventory.list.InventoryModel"
    ],

    controller: "inventory-inventory",
    viewModel: {
        type: "inventory-inventory"
    },
    closable: true,

    listeners:{
        refreshList: 'onRefreshList'
    },


    layout:{
        type: 'hbox',
        align: 'stretch'
    },
    items:[
        {
            xtype: 'grid',
            flex: 1,

            tbar:[
                {xtype: 'button', text: 'New Item', handler: 'newInventoryItem'}
            ],

            bind:{
                store: '{inventory}'
            },

            listeners:{
                itemclick: 'showDetails'
            },

            columns:[
                { text: 'Name', dataIndex: 'name', flex: 1 },
                { text: 'Price', dataIndex: 'price' },
                { text: 'Active', dataIndex: 'active' },
            ]
        }
    ]
});
单击行时,将创建一个新的详图面板,选定的记录将链接到其viewmodel,并将其添加到保存栅格的容器视图中。我还希望在创建新库存记录时使用相同的详细信息面板,因此我提取了用于创建和编辑的共享逻辑,以便可以在控制器中重用

以下是列表的控制器:

Ext.define('InventoryDemo.view.inventory.list.InventoryController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.inventory-inventory',

    config:{
        // holds the newly created detail panel
        detailsPanel: null
    },

    showDetails: function (grid, record, item, index, e, eOpts){
        this.createDetailsPanel();
        this.addTitleToDetailsPanel(record.get('name'));

        // This creates the link in the new detail panel's viewmodel for the
        // selected record. We specifically do NOT do this in the
        // `newInventoryItem`.
        details.getViewModel().linkTo('inventoryitem', record);

        this.addDetailsPanelToView();
    },

    newInventoryItem: function (button, e){
        this.createDetailsPanel();
        this.addTitleToDetailsPanel('New Item');

        // I thought that because the previous panel was destroyed during the
        // `createDetailsPanel` method any previously linked record would not
        // be linked to the new detail panel created and that not linking here
        // would give me an empty detail panel.
        this.addDetailsPanelToView();
    },


    createDetailsPanel: function (){
        if(this.getDetailsPanel() !== null){
            // I'm destroying any previous view here which, as I understand, 
            // would also destroy the the associated ViewController and ViewModel
            // which would also kill any links to the viewmodel
            this.getDetailsPanel().destroy();
        }

        details = Ext.create('InventoryDemo.view.inventory.details.Inventory',{
            session: true,
            listeners:{
                refreshList: 'onRefreshList'
            }
        });
        this.setDetailsPanel(details);
    },

    addDetailsPanelToView: function (){
        this.getView().add(this.getDetailsPanel());
    },

    addTitleToDetailsPanel: function (title){
        this.getDetailsPanel().setTitle("<h3>" + title + "</h3>");
    },

    onRefreshList: function (){
        this.getViewModel().get('inventory').load();
    }
});
Ext.define('APP.controller.TheView',{
    extend: "Ext.app.ViewController",
    alias: 'controller.theView',

    onOpenDetail: function(){

        var detail = this.lookupReference('detail');

        if(!detail){

            var view = this.getView(),
                detailConfig = view.getDetailConfig(),
                theProperty = this.getViewModel().get('theProperty');

            detailConfig = Ext.apply({
                viewModel: {
                    // This actually gets correctly merged with whatever there is
                    // in the viewModel configuration of the detail
                    data: { theProperty: theProperty }
                }
            }, detailConfig));

            detail = view.add(detailConfig);
        }

        // Do something with the detail instance
    }
};
我遇到的问题是,如果我单击一行以查看其有效的详细信息,然后单击“新建项目”按钮,则在上一个详细信息面板上加载的记录仍将加载到新的详细信息面板上

如果我先点击“新建项目”按钮,我会得到我要的空白表格,如果我选择不同的项目行,每一个记录从所选行加载到详细面板中,这不是一个情况下,第一行的记录被困在细节面板中,但是一旦我选择了一行,“新建项目”按钮将仅为我提供具有以前加载的记录的表单


在销毁和创建两个单独的视图/视图模型/视图控制器之间,是否有某种东西会使指向视图模型的链接持续存在,或者我的控制器逻辑中是否存在我没有看到的缺陷

> P>如果在细节视图模型中唯一需要的是你试图链接到的这个奇异属性,考虑不要使用一个独立的VIEW模型来实现细节。

当详细信息面板位于资源清册视图的项目中时,它实际上可以自然访问视图的viewModel detailPanel。lookupViewModel将返回组件树层次结构中最接近的单个viewModel。绑定也应该起作用

但是,如果需要为“详图”面板创建单独的viewModel,则可以使用特殊的viewModel配置创建详图视图,该配置在实例化时会合并到详图的viewModel中

观点:

Ext.define('APP.view.TheView',{
    extend: "Ext.container.Container",
    alias: 'widget.theView',

    controller: 'theView',
    viewModel: { type: 'theView' },

    config: {
        detailConfig: { xtype: 'theDetail', reference: 'detail' }
    },

    items: ...
};
视图的viewController:

Ext.define('InventoryDemo.view.inventory.list.InventoryController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.inventory-inventory',

    config:{
        // holds the newly created detail panel
        detailsPanel: null
    },

    showDetails: function (grid, record, item, index, e, eOpts){
        this.createDetailsPanel();
        this.addTitleToDetailsPanel(record.get('name'));

        // This creates the link in the new detail panel's viewmodel for the
        // selected record. We specifically do NOT do this in the
        // `newInventoryItem`.
        details.getViewModel().linkTo('inventoryitem', record);

        this.addDetailsPanelToView();
    },

    newInventoryItem: function (button, e){
        this.createDetailsPanel();
        this.addTitleToDetailsPanel('New Item');

        // I thought that because the previous panel was destroyed during the
        // `createDetailsPanel` method any previously linked record would not
        // be linked to the new detail panel created and that not linking here
        // would give me an empty detail panel.
        this.addDetailsPanelToView();
    },


    createDetailsPanel: function (){
        if(this.getDetailsPanel() !== null){
            // I'm destroying any previous view here which, as I understand, 
            // would also destroy the the associated ViewController and ViewModel
            // which would also kill any links to the viewmodel
            this.getDetailsPanel().destroy();
        }

        details = Ext.create('InventoryDemo.view.inventory.details.Inventory',{
            session: true,
            listeners:{
                refreshList: 'onRefreshList'
            }
        });
        this.setDetailsPanel(details);
    },

    addDetailsPanelToView: function (){
        this.getView().add(this.getDetailsPanel());
    },

    addTitleToDetailsPanel: function (title){
        this.getDetailsPanel().setTitle("<h3>" + title + "</h3>");
    },

    onRefreshList: function (){
        this.getViewModel().get('inventory').load();
    }
});
Ext.define('APP.controller.TheView',{
    extend: "Ext.app.ViewController",
    alias: 'controller.theView',

    onOpenDetail: function(){

        var detail = this.lookupReference('detail');

        if(!detail){

            var view = this.getView(),
                detailConfig = view.getDetailConfig(),
                theProperty = this.getViewModel().get('theProperty');

            detailConfig = Ext.apply({
                viewModel: {
                    // This actually gets correctly merged with whatever there is
                    // in the viewModel configuration of the detail
                    data: { theProperty: theProperty }
                }
            }, detailConfig));

            detail = view.add(detailConfig);
        }

        // Do something with the detail instance
    }
};
详情如下:

Ext.define('APP.view.TheDetail',{
    extend: "Ext.panel.Panel",
    alias: 'widget.theDetail',

    controller: 'theDetail',
    viewModel: { type: 'theDetail' },

    items: ...
};
希望这有点帮助!:-