extjs contextmenu 单击错误 - 找不到方法......但在错误的控制器中查找
extjs contextmenu click error - method not found... but looking in wrong controller
如何单击此菜单项以启动控制器中的方法。
项目点击成功,但错误消息指出 ExtApplication4.view.main.MainController 上没有名为 "onDownloadTopdayRecapContextButton" 的方法。就是这个问题,你可以看到视图的控制器是 portalRealtime-portalRealtime.
所以它以某种方式指向了错误的控制器。有人可以告诉我我做错了什么吗?
菜单代码
var contextMenuTopday = Ext.create('Ext.menu.Menu', {
items: [{
text: 'Download Topday Recap',
iconCls: 'downloadIcon',
listeners: {
click: 'onDownloadTopdayRecapContextButton'
}
网格菜单保存在
Ext.define('ExtApplication4.view.portalRealtime.PortalRealtime', {
extend: 'Ext.panel.Panel',
xtype: 'app-portalRealtime',
itemId: 'portalRealtimeItemID',
requires: [
'ExtApplication4.view.portalRealtime.PortalRealtimeController',
'Ext.form.action.StandardSubmit'
],
controller: 'portalRealtime-portalRealtime',
title: 'Main Portal',
layout: {
type: 'vbox'
},
items: [
//i deleted some grid code here
collapsible: true,
collapseDirection: 'left',
listeners: {
itemcontextmenu: function (view, rec, node, index, e) {
e.stopEvent();
contextMenuTopday.showAt(e.getXY());
return false;
}
{
您正在视图之外创建上下文菜单,因此它不会继承您的控制器。
在使用下面的代码之前,请滚动到答案的底部以获得更好的解决方案,但这有望说明问题的原因。
如果这不能解决您的问题,请发表评论并提供更完整的代码示例,我会更新我的答案
在这些情况下,您可以手动传递一个控制器,但您需要作为父控制器传递,因为如果您在多个组件上重复使用相同的控制器(例如,当您销毁一个控制器时,它破坏了控制器,而另一个没有)
所以您可以像这样在您的视图中创建:
Ext.define('ExtApplication4.view.portalRealtime.PortalRealtime', {
initComponent:function(){
this.callParent(arguments);
this.contextMenuTopday = Ext.create('Ext.menu.Menu', {
controller:{
parent: this.getController()
},
items: [{
text: 'Download Topday Recap',
iconCls: 'downloadIcon',
listeners: {
click: 'onDownloadTopdayRecapContextButton'
}
}]
});
}
然后,您可以访问 contextMenuTopday 属性,而不是使用变量来访问上下文菜单,因为您在子项目中,您可能需要遍历到您的实际视图,这是执行此操作的最简单方法通过组件上可用的 up 方法,您需要确保包含一个 xtype 来执行此操作:
Ext.define('ExtApplication4.view.portalRealtime.PortalRealtime', {
xtype:'portalrealtime'
然后您可以在上下文菜单中执行以下操作:
itemcontextmenu: function (view, rec, node, index, e) {
this.up('portalrealtime').contextMenuTopday.showAt(e.getXY());
}
更好的方法
最好看这个fiddle:https://fiddle.sencha.com/#view/editor&fiddle/1qpn
将您的菜单定义为自己的菜单class:
Ext.define('Example.ContextMenu', {
xtype:'testmenu',
extend:'Ext.menu.Menu',
items: [{
text: 'Download Topday Recap',
iconCls: 'downloadIcon',
listeners: {
click: 'onDownloadTopdayRecapContextButton'
}
}]
});
在您的控制器上为 itemcontextmenu 事件使用一个方法(无论如何这都很好,因为它提供了更好的关注点分离):
项目上下文菜单:'showContextMenu'
然后向您的 portalRealtime-portalRealtime
控制器添加一些新方法:
getContextMenu:function(){
if(!this.contextMenu){
this.contextMenu = this.getView().add({xtype:'testmenu'});
}
return this.contextMenu;
},
showContextMenu:function (view, rec, node, index, e) {
// we can't use showAt now we have added this to our view, as it would be positioned relatively.
this.getContextMenu().show().setPagePosition(e.getXY());
}
我们在这里做的是将上下文菜单添加到视图,因此它继承了控制器(如果提供的话,还有一个视图模型)。
在控制器上为 listeners/button 处理程序等调用方法的最佳方法是仅将方法名称指定为字符串,即:
listeners:{
itemcontextmenu: 'showContextMenu'
}
这将自动查找负责的控制器并使用正确的方法。
如果您需要从组件内部调用,您会发现 this.getController()
失败,除非您调用控制器附加到的实际组件 - 即您是从子组件调用。在这些情况下,您可以使用 this.lookupController()
找到 inherited/responsible 控制器,然后从此处调用任何方法,例如this.lookupController().myMethod()
如何单击此菜单项以启动控制器中的方法。 项目点击成功,但错误消息指出 ExtApplication4.view.main.MainController 上没有名为 "onDownloadTopdayRecapContextButton" 的方法。就是这个问题,你可以看到视图的控制器是 portalRealtime-portalRealtime.
所以它以某种方式指向了错误的控制器。有人可以告诉我我做错了什么吗?
菜单代码
var contextMenuTopday = Ext.create('Ext.menu.Menu', {
items: [{
text: 'Download Topday Recap',
iconCls: 'downloadIcon',
listeners: {
click: 'onDownloadTopdayRecapContextButton'
}
网格菜单保存在
Ext.define('ExtApplication4.view.portalRealtime.PortalRealtime', {
extend: 'Ext.panel.Panel',
xtype: 'app-portalRealtime',
itemId: 'portalRealtimeItemID',
requires: [
'ExtApplication4.view.portalRealtime.PortalRealtimeController',
'Ext.form.action.StandardSubmit'
],
controller: 'portalRealtime-portalRealtime',
title: 'Main Portal',
layout: {
type: 'vbox'
},
items: [
//i deleted some grid code here
collapsible: true,
collapseDirection: 'left',
listeners: {
itemcontextmenu: function (view, rec, node, index, e) {
e.stopEvent();
contextMenuTopday.showAt(e.getXY());
return false;
}
{
您正在视图之外创建上下文菜单,因此它不会继承您的控制器。
在使用下面的代码之前,请滚动到答案的底部以获得更好的解决方案,但这有望说明问题的原因。
如果这不能解决您的问题,请发表评论并提供更完整的代码示例,我会更新我的答案
在这些情况下,您可以手动传递一个控制器,但您需要作为父控制器传递,因为如果您在多个组件上重复使用相同的控制器(例如,当您销毁一个控制器时,它破坏了控制器,而另一个没有)
所以您可以像这样在您的视图中创建:
Ext.define('ExtApplication4.view.portalRealtime.PortalRealtime', {
initComponent:function(){
this.callParent(arguments);
this.contextMenuTopday = Ext.create('Ext.menu.Menu', {
controller:{
parent: this.getController()
},
items: [{
text: 'Download Topday Recap',
iconCls: 'downloadIcon',
listeners: {
click: 'onDownloadTopdayRecapContextButton'
}
}]
});
}
然后,您可以访问 contextMenuTopday 属性,而不是使用变量来访问上下文菜单,因为您在子项目中,您可能需要遍历到您的实际视图,这是执行此操作的最简单方法通过组件上可用的 up 方法,您需要确保包含一个 xtype 来执行此操作:
Ext.define('ExtApplication4.view.portalRealtime.PortalRealtime', {
xtype:'portalrealtime'
然后您可以在上下文菜单中执行以下操作:
itemcontextmenu: function (view, rec, node, index, e) {
this.up('portalrealtime').contextMenuTopday.showAt(e.getXY());
}
更好的方法
最好看这个fiddle:https://fiddle.sencha.com/#view/editor&fiddle/1qpn
将您的菜单定义为自己的菜单class:
Ext.define('Example.ContextMenu', {
xtype:'testmenu',
extend:'Ext.menu.Menu',
items: [{
text: 'Download Topday Recap',
iconCls: 'downloadIcon',
listeners: {
click: 'onDownloadTopdayRecapContextButton'
}
}]
});
在您的控制器上为 itemcontextmenu 事件使用一个方法(无论如何这都很好,因为它提供了更好的关注点分离): 项目上下文菜单:'showContextMenu'
然后向您的 portalRealtime-portalRealtime
控制器添加一些新方法:
getContextMenu:function(){
if(!this.contextMenu){
this.contextMenu = this.getView().add({xtype:'testmenu'});
}
return this.contextMenu;
},
showContextMenu:function (view, rec, node, index, e) {
// we can't use showAt now we have added this to our view, as it would be positioned relatively.
this.getContextMenu().show().setPagePosition(e.getXY());
}
我们在这里做的是将上下文菜单添加到视图,因此它继承了控制器(如果提供的话,还有一个视图模型)。
在控制器上为 listeners/button 处理程序等调用方法的最佳方法是仅将方法名称指定为字符串,即:
listeners:{
itemcontextmenu: 'showContextMenu'
}
这将自动查找负责的控制器并使用正确的方法。
如果您需要从组件内部调用,您会发现 this.getController()
失败,除非您调用控制器附加到的实际组件 - 即您是从子组件调用。在这些情况下,您可以使用 this.lookupController()
找到 inherited/responsible 控制器,然后从此处调用任何方法,例如this.lookupController().myMethod()