Я уверен, что здесь кое-что отсутствует, и я просто не вижу, что это такое.Похоже, что ViewModel сохраняется после того, как его вид разрушен в 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' },
]
}
]
});
При нажатии на строку, новая панель деталь создана и выбранная запись связана с его 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("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
даст мне только формы с ранее загруженной записью.
Есть ли что-то, что могло бы сделать ссылку на viewmodel, сохраняться между уничтожением и созданием двух отдельных представлений/viewmodels/viewcontrollers (или есть недостаток в моей логике контроллера, который я просто не вижу)?