现代工具包中的 Extjs 选项卡面板 tabchange 事件
Extjs Tab Panel tabchange event in modern toolkit
我正在使用 ExtJS 7.5 现代工具包。我最初在经典工具包中开发了一个带有路由器的应用程序,该应用程序基于下面显示的示例,使用路由器并监听选项卡面板上的 tabchange 事件。我们决定为应用程序更改为现代工具包,但我似乎无法弄清楚如何复制 tabchange 行为,因为现代工具包中似乎不存在 tabchange 事件。
我能找到的最接近的事情是 activeitemchange 事件,但在使用路线时这会成为一个问题,因为在处理路线时我需要更新触发该事件的活动选项卡,随后导致另一个重定向到另一条路线。 tabchange 事件不受设置活动项目的影响,似乎只受到实际单击/触摸另一个选项卡的影响。
经典工具包中的示例:
Ext.define('Router.controller.Navigation', {
extend: 'Ext.app.Controller',
config: {
control: {
'#main-tabs': {
tabchange: 'onTabChange'
},
'#tab6': {
tabchange: 'onChildTabChange'
}
},
refs: {
tabPanel: '#main-tabs'
},
routes: {
'main-tabs:id:subid': {
action: 'showTab',
before: 'beforeShowTab',
conditions: {
// take control of the :id & :subid parameters, make them optional but delimited by colon
':id': '(?:(?::){1}([%a-zA-Z0-9\-\_\s,]+))?',
':subid': '(?:(?::){1}([%a-zA-Z0-9\-\_\s,]+))?'
}
}
}
},
onTabChange: function(tabPanel, newItem) {
var id = newItem.getId(),
child = newItem.child('tabpanel'),
subid = '',
hash = 'main-tabs:' + id;
if (child) {
newItem = child.getActiveTab();
subid = ':' + newItem.getId();
hash += subid;
}
this.redirectTo(hash);
},
onChildTabChange: function(tabPanel, newItem) {
var parentTab = tabPanel.up(),
parentId = parentTab.getId(),
hash = 'main-tabs:' + parentId + ':' + newItem.getId();
this.redirectTo(hash);
},
beforeShowTab: function(id, subid, action) {
var tabPanel = this.getTabPanel(),
child;
if (!id) {
// no id was specified, use 0 index to resolve child
id = 0;
}
child = tabPanel.getComponent(id);
if (child) {
// tab found, resume the action
action.resume();
}
else {
Ext.Msg.alert('Tab Not Found', 'Tab with id or index "<b>' + id + '</b>" was not found!');
// child not found, stop action
action.stop();
}
},
showTab: function(id, subid) {
var tabPanel = this.getTabPanel(),
child, childTabPanel;
if (!id) {
// no id was specified, use 0 index to resolve child
id = 0;
}
child = tabPanel.getComponent(id);
childTabPanel = child.child('tabpanel');
tabPanel.setActiveTab(child);
if (childTabPanel) {
if (!subid) {
subid = 0;
}
childTabPanel.setActiveTab(subid);
}
}
});
Ext.application({
name: 'Router',
requires: [
'Ext.tab.Panel',
'Ext.window.MessageBox'
],
controllers: [
'Navigation'
],
defaultToken: 'main-tabs',
launch: function() {
Ext.create('Ext.tab.Panel', {
renderTo: Ext.getBody(),
id: 'main-tabs',
height: 300,
width: 600,
activeTab: 0,
defaults: {
padding: 10
},
items: [
{
title: 'Tab 1',
id: 'tab1',
layout: 'fit',
items: [
{
xtype: 'tabpanel',
id: 'tab6',
items: [
{
title: 'Sub-tab 1',
id: 'subtab1'
},
{
title: 'Sub-tab 2',
id: 'subtab2'
},
{
title: 'Sub-tab 3',
id: 'subtab3'
}
]
}
]
},
{
title: 'Tab 2',
id: 'tab2',
html: 'Tab 2 content'
},
{
title: 'Tab 3',
id: 'tab3',
html: 'Tab 3 content'
},
{
title: 'Tab 4',
id: 'tab4',
html: 'Tab 4 content'
},
{
title: 'Tab 5',
id: 'tab5',
html: 'Tab 5 content'
}
]
});
}
});
现代的正确事件是activeitemchange
xtype: 'tabpanel',
...
listeners: {
activeitemchange: function(tabpanel, newTab) {
console.log(newTab.getId());
}
}
监听 activeitemchange 事件时,我在使用后退/前进浏览器按钮、处理路由和使用 tabpanel.setActiveItem() 时会遇到问题。这将触发 activeitemchange 事件,导致另一个(不必要的重定向)。
我改为使用 beforeactiveitemchange 事件,它允许我在设置活动项目时暂停处理程序中的事件,因此不再发生重定向并且活动项目更改仍按预期运行。
control: {
'#main-tabs': {
beforeactiveitemchange: 'onMainTabChange'
},
}
//Within the handler func that handles the route
tabPanel.suspendEvent('beforeactiveitemchange');
tabPanel.setActiveItem(tab);
tabPanel.resumeEvent('beforeactiveitemchange');
我正在使用 ExtJS 7.5 现代工具包。我最初在经典工具包中开发了一个带有路由器的应用程序,该应用程序基于下面显示的示例,使用路由器并监听选项卡面板上的 tabchange 事件。我们决定为应用程序更改为现代工具包,但我似乎无法弄清楚如何复制 tabchange 行为,因为现代工具包中似乎不存在 tabchange 事件。
我能找到的最接近的事情是 activeitemchange 事件,但在使用路线时这会成为一个问题,因为在处理路线时我需要更新触发该事件的活动选项卡,随后导致另一个重定向到另一条路线。 tabchange 事件不受设置活动项目的影响,似乎只受到实际单击/触摸另一个选项卡的影响。
经典工具包中的示例:
Ext.define('Router.controller.Navigation', {
extend: 'Ext.app.Controller',
config: {
control: {
'#main-tabs': {
tabchange: 'onTabChange'
},
'#tab6': {
tabchange: 'onChildTabChange'
}
},
refs: {
tabPanel: '#main-tabs'
},
routes: {
'main-tabs:id:subid': {
action: 'showTab',
before: 'beforeShowTab',
conditions: {
// take control of the :id & :subid parameters, make them optional but delimited by colon
':id': '(?:(?::){1}([%a-zA-Z0-9\-\_\s,]+))?',
':subid': '(?:(?::){1}([%a-zA-Z0-9\-\_\s,]+))?'
}
}
}
},
onTabChange: function(tabPanel, newItem) {
var id = newItem.getId(),
child = newItem.child('tabpanel'),
subid = '',
hash = 'main-tabs:' + id;
if (child) {
newItem = child.getActiveTab();
subid = ':' + newItem.getId();
hash += subid;
}
this.redirectTo(hash);
},
onChildTabChange: function(tabPanel, newItem) {
var parentTab = tabPanel.up(),
parentId = parentTab.getId(),
hash = 'main-tabs:' + parentId + ':' + newItem.getId();
this.redirectTo(hash);
},
beforeShowTab: function(id, subid, action) {
var tabPanel = this.getTabPanel(),
child;
if (!id) {
// no id was specified, use 0 index to resolve child
id = 0;
}
child = tabPanel.getComponent(id);
if (child) {
// tab found, resume the action
action.resume();
}
else {
Ext.Msg.alert('Tab Not Found', 'Tab with id or index "<b>' + id + '</b>" was not found!');
// child not found, stop action
action.stop();
}
},
showTab: function(id, subid) {
var tabPanel = this.getTabPanel(),
child, childTabPanel;
if (!id) {
// no id was specified, use 0 index to resolve child
id = 0;
}
child = tabPanel.getComponent(id);
childTabPanel = child.child('tabpanel');
tabPanel.setActiveTab(child);
if (childTabPanel) {
if (!subid) {
subid = 0;
}
childTabPanel.setActiveTab(subid);
}
}
});
Ext.application({
name: 'Router',
requires: [
'Ext.tab.Panel',
'Ext.window.MessageBox'
],
controllers: [
'Navigation'
],
defaultToken: 'main-tabs',
launch: function() {
Ext.create('Ext.tab.Panel', {
renderTo: Ext.getBody(),
id: 'main-tabs',
height: 300,
width: 600,
activeTab: 0,
defaults: {
padding: 10
},
items: [
{
title: 'Tab 1',
id: 'tab1',
layout: 'fit',
items: [
{
xtype: 'tabpanel',
id: 'tab6',
items: [
{
title: 'Sub-tab 1',
id: 'subtab1'
},
{
title: 'Sub-tab 2',
id: 'subtab2'
},
{
title: 'Sub-tab 3',
id: 'subtab3'
}
]
}
]
},
{
title: 'Tab 2',
id: 'tab2',
html: 'Tab 2 content'
},
{
title: 'Tab 3',
id: 'tab3',
html: 'Tab 3 content'
},
{
title: 'Tab 4',
id: 'tab4',
html: 'Tab 4 content'
},
{
title: 'Tab 5',
id: 'tab5',
html: 'Tab 5 content'
}
]
});
}
});
现代的正确事件是activeitemchange
xtype: 'tabpanel',
...
listeners: {
activeitemchange: function(tabpanel, newTab) {
console.log(newTab.getId());
}
}
监听 activeitemchange 事件时,我在使用后退/前进浏览器按钮、处理路由和使用 tabpanel.setActiveItem() 时会遇到问题。这将触发 activeitemchange 事件,导致另一个(不必要的重定向)。
我改为使用 beforeactiveitemchange 事件,它允许我在设置活动项目时暂停处理程序中的事件,因此不再发生重定向并且活动项目更改仍按预期运行。
control: {
'#main-tabs': {
beforeactiveitemchange: 'onMainTabChange'
},
}
//Within the handler func that handles the route
tabPanel.suspendEvent('beforeactiveitemchange');
tabPanel.setActiveItem(tab);
tabPanel.resumeEvent('beforeactiveitemchange');