我如何指向该菜单项,单击以在控制器中启动方法。
项目单击已成功命中,但错误消息指出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());
}
更好的方法
最好的说明是看这个小提琴:https://fiddle.sencha.com/#view/editor&fiddle/1qpn
将菜单定义为自己的类:
Ext.define('Example.ContextMenu', {
xtype:'testmenu',
extend:'Ext.menu.Menu',
items: [{
text: 'Download Topday Recap',
iconCls: 'downloadIcon',
listeners: {
click: 'onDownloadTopdayRecapContextButton'
}
}]
});
在您的控制器上为itemcontextmenu事件使用一种方法(无论如何,这很好,因为它可以更好地分离关注点):
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:{
itemcontextmenu: 'showContextMenu'
}
这将自动查找负责的控制器并使用正确的方法。
如果您需要从一个组件内调用,您会发现
this.getController()
失败,除非您调用该控制器所连接的实际组件-即从子组件进行调用。在这些情况下,您可以使用this.lookupController()
查找继承/负责的控制器,然后从此处调用任何方法,例如this.lookupController().myMethod()