0

ここで何かが欠けていると確信しており、それが何であるかがわかりません。

私はextjs 6で構築しているデモプロジェクトを持っています。その中に在庫アイテムのグリッドがあります。

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' },
            ]
        }
    ]
});

行をクリックすると、新しい詳細パネルが作成され、選択したレコードがそのビューモデルにリンクされ、グリッドを保持するコンテナー ビューに追加されます。新しい在庫レコードを作成するときにも同じ詳細パネルを使用したいので、コントローラーで再利用できるように、作成および編集用の共有ロジックを抽出しました。

リストのコントローラーは次のとおりです。

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("InventoryDemo.view.inventory.details.Inventory",{
    extend: "Ext.form.Panel",

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

    controller: "inventory-details-inventory",
    viewModel: {
        type: "inventory-details-inventory"
    },

    flex: 1,
    closable: true,
    bodyPadding: 10,
    reference: 'inventorydetails',
    defaults:{
        layout: 'anchor',
        anchor: '50%'
    },
    dockedItems:[
        {
            xtype: 'toolbar',
            dock: 'bottom',
            ui: 'footer',
            items:[
                {xtype: 'button', text: 'Update', handler: 'updateRecord'},
                {xtype: 'button', text: 'Delete', handler: 'deleteRecord'}
            ]
        }
    ],

    items:[
        {
            xtype: 'hiddenfield',
            name: '_method',
            value: 'PUT'
        },
        {
            xtype: 'fieldset',
            title: 'IDs',
            collapsible: true,
            defaults:{
                xtype: 'textfield'
            },
            items:[
                {
                    name: 'id',
                    fieldLabel: 'ID',
                    readOnly: true,
                    bind: '{inventoryitem.id}'
                },
                {
                    name: 'brand_id',
                    fieldLabel: 'Brand ID',
                    readOnly: true,
                    bind: '{inventoryitem.brand_id}'
                }
            ]
        },
        {
            xtype: 'fieldset',
            title: 'Details',
            defaults:{
                xtype: 'textfield'
            },
            items:[
                {
                    name: 'name',
                    fieldLabel: 'Name',
                    bind: '{inventoryitem.name}'
                },
                {
                    name: 'price',
                    fieldLabel: 'Price',
                    bind: '{inventoryitem.price}'
                }
            ]
        }
    ]

});

私が遭遇している問題は、行をクリックしてその詳細を表示し (動作します)、New Itemボタンをクリックすると、前の詳細パネルにロードされたレコードがまだ新しい詳細パネルにロードされていることです。

最初にボタンをクリックするNew Itemと、目的の空白のフォームが表示され、別のアイテム行を選択すると、選択した行の各レコードが詳細パネルに正しく読み込まれます (最初の行のレコードが表示される状況ではありません)。詳細パネルで「立ち往生」)、行を選択するとすぐに、New Itemボタンは以前に読み込まれたレコードを含むフォームのみを表示します。

ビューモデルへのリンクを2つの別々のビュー/ビューモデル/ビューコントローラーの破壊と作成の間で持続させるものはありますか(または、コントローラーロジックに私が見ていない欠陥がありますか)?

4

1 に答える 1