2015-10-13 64 views
0

破坏后,我敢肯定有我丢失的东西在这里,我看不出它是什么样的视图模型仍然存在。似乎它的观点是在ExtJS的

我演示项目中,我建设的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按钮只会给我先前加载的记录表格。

有没有什么东西可以使视图模型的链接在两个单独的视图/ viewmodels/viewcontrollers的破坏和创建之间持续存在(或者我的控制器逻辑中存在一个我只是没有看到的缺陷)?

回答

0

如果在详细的视图模型唯一需要的是您要链接到,可以考虑不使用独立的视图模型的细节,在这一切的奇异特性。

当您的详细信息面板驻留在您的inventory视图的项目中时,它实际上可以自然地访问视图的viewModel(detailPanel.lookupViewModel()将返回组件树层次结构中单个最接近的viewModel)。绑定也应该起作用。但是,如果您需要单独的viewModel作为详细信息面板,则可以使用ad-hoc 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('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: ... 
}; 

希望这有助于一点点! :-)