我如何指向该菜单项,单击以在控制器中启动方法。
项目单击已成功命中,但错误消息指出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()

08-18 11:27
查看更多