0

我有这个网格面板:

Ext.define('BM.view.test.MacroList', {
extend: 'BM.view.GridPanel',
alias:'widget.macro-test-list',

store: 'Tests',

initComponent: function() {

    this.columns = [
        {
            xtype:'actioncolumn',
            width:50,
            items: [
            {
                icon: 'images/start.png',
                tooltip: 'Start Test',
                handler: function(grid, rowIndex, colIndex) {
                    this.application.fireEvent('testStart', grid.getStore().getAt(rowIndex)); 
                // application not defined here because 'this' is the button.
                }]
     }]
}
}

stratTest 是一个可以在应用程序的许多地方使用的函数,我希望它可以用作应用程序范围的事件,但这些似乎只能从控制器中获得。
如何.application.fireEvent('testStart'...)从该按钮内的处理程序调用?

将此问题用作对事件和 Sencha 文档的持续参考,但找不到答案。

4

3 回答 3

6

您进入this.application控制器范围。

鉴于您显然在这里使用 MVC,我会说最好坚持 MVC 概念;也就是说,为了可重用性,组件不应该知道哪个控制器使用它,而控制器应该知道它正在使用哪些组件。

所以你应该真正在控制器中监听事件,并从那里触发一个应用程序事件。

问题是控制器无法访问 actioncolumn 处理程序(它在内部调用Ext.grid.column.Action processEvent())。

所以最好的办法是在视图中触发一个新事件:

this.columns = [
    {
        xtype:'actioncolumn',
        ...
        items: [
        {
            ...
            handler: function( aGrid, aRowIndex, aColIndex, aItem, aEvent, aRecord ) {
                this.fireEvent( 'columnaction', aGrid, aRowIndex, aColIndex, aItem, aEvent, aRecord); }
        }]
 }]

另请注意,您可以为该列定义一个全局处理程序,如下所示:

this.columns = [
    {
        xtype:'actioncolumn',

        handler: function( aGrid, aRowIndex, aColIndex, aItem, aEvent, aRecord ) {
            this.fireEvent( 'columnaction', aGrid, aRowIndex, aColIndex, aItem, aEvent, aRecord); }

        ...
        items: [
        {
            ...
        }]
 }]

然后在控制器中捕获这个事件。

init: function() {
    this.control({
        'macro-test-list actioncolumn':{
            columnaction: this.onAction
        }
    });
},

onAction: function( aGrid, aRowIndex, aColIndex, aItem, aEvent, aRecord ) {
    this.application.fireEvent( 'testStart', aGrid.getStore().getAt( aRowIndex ) );
}

请注意,顺便说一下,鉴于您正在尝试做的事情,更简洁的代码将是:

onAction: function( aGrid, aRowIndex, aColIndex, aItem, aEvent, aRecord ) {
    this.application.fireEvent( 'testStart', aRecord );
}
于 2012-09-02T10:32:12.193 回答
4

在触发应用程序范围的自定义事件方面,ExtJS V5.1 发布后现在有一个新方法,即使用 Ext.GlobalEvents。

当你触发事件时,你这样做:

Ext.GlobalEvents.fireEvent('custom_event',args); 

当您注册事件的处理程序时,您执行以下操作:

var obj = Ext.create('Ext.form.Panel', {
  // ....
});
Ext.GlobalEvents.on('custom_event', function(arguments){
  /* handler codes*/
}, obj}; 

此方法不限于控制器。任何组件都可以通过将组件对象作为输入参数范围来处理自定义事件。

这是一个小提琴

于 2015-07-17T14:48:05.340 回答
0

APPNAME.getApplication.fireEvent() 在应用程序范围内可用。

于 2013-10-23T08:09:29.577 回答