2017-02-22 15 views
3

Как указать этот пункт меню, чтобы запустить метод в контроллере. Щелчок элемента успешно удаляется, но в сообщении об ошибке нет метода с именем «onDownloadTopdayRecapContextButton» на ExtApplication4.view.main.MainController. В этом и проблема, вы можете видеть, что контроллер вида - portalRealtime-portalRealtime.extjs contextmenu click error - метод не найден ... но ищет неправильный контроллер

Так или иначе, это указывает на неправильный контроллер. Может ли кто-нибудь показать мне, что я делаю неправильно?

код меню меню сетки

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; 
       } 
{ 

ответ

3

Вы создаете контекстное меню за пределами вашей точки зрения, так что не наследует контроллер.

Перед тем, как использовать приведенный ниже код, прокрутите в нижней части ответа для лучшего решения, но это, надеюсь, показывает, в чем причина вашей проблемы.

Если это не решит проблему, пожалуйста, комментарий и обеспечить более полный пример кода, и я буду обновлять мой ответ

В этих случаях вы можете передать контроллер вручную, но вам нужно передайте в качестве родителя, поскольку у вас возникнут всевозможные проблемы, если вы повторно используете один и тот же контроллер на нескольких компонентах (например, когда вы уничтожаете один из них, он уничтожает контроллер, оставаясь без него)

Таким образом, вы можете создать из в вашем представлении:

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

Define ваше меню в качестве своего класса:

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()); 

} 

То, что мы делаем здесь, добавление контекстного меню к представлению, поэтому он наследует контроллер (и ViewModel, если это предусмотрено).

Лучший способ для вызова методов контроллера для слушателей кнопок/обработчиков и т.д., это просто указать имя метода в виде строки, т.е.:

listeners:{ 
    itemcontextmenu: 'showContextMenu' 
} 

Это будет автоматически искать ответственного контроллера и использовать правильный метод.

Если вам нужно позвонить изнутри компонента, вы обнаружите, что this.getController() сбой, если вы не вызываете фактический компонент, к которому подключен контроллер, то есть вы вызываете из дочернего компонента. В этих случаях вы можете использовать this.lookupController(), чтобы найти унаследованный/ответственный контроллер, а затем вызвать любые методы отсюда, например. this.lookupController().myMethod()

+0

благодарит Тео, я полностью готов к ЛУЧШЕЙ ПУТЬ. Поэтому я вижу, что мне нужно добавить несколько методов, как вы описали. Мой вопрос в том, где я могу добавить эти методы? ... в контроллере, который я пытаюсь ударить? , и из сетки в представлении, как мне запустить методы, которые вы создаете? – solarissf

+0

@solarissf Я обновил ответ с дополнительной информацией об этом. – Theo

+0

ОК, поэтому методы в контроллере вызываются ...после того, как он попадает в getContextMenu, я получаю ошибку в строке Ext.create ('Ext.menu.Menu. ошибка - это ошибка uncaught: нет типа, указанного для controller.create. Любая идея? – solarissf

Смежные вопросы