如何在extjs app控制器中控制事件侦听器的范围

时间:2018-06-11 11:49:14

标签: javascript extjs extjs6

Ext JS - v 6.2.1

我对重新使用ExtJs中开发的主要组件感兴趣,我在tabpanel的不同标签中写了这个组件。主要组件由两个子组件组成,每个组件都有各自的控制器,子组件之间相互作用。由于事件侦听器已添加到控制器域中,因此在一个选项卡实例中触发的事件也会影响其他选项卡。

场景的伪代码解释

*********** Views ***********

Ext.define('MainApp.view.main.Main', {
    extend: 'Ext.tab.Panel',
    xtype: 'mainapp-main',  
    controller: 'main',

    ...

    items: [{
        title: 'Main Component Instance 1',
        closable: true,
        items: [{
            xtype: 'mainapp-maincomponent'
        }]
    }, {
        title: 'Main Component Instance 2',
        closable: true,
        items: [{
            xtype: 'mainapp-maincomponent'
        }]
    }]
});


Ext.define('MainApp.view.maincomponent.MainComponent', {
    extend: 'Ext.panel.Panel',
    xtype: 'mainapp-maincomponent',
    controller: 'maincomponent',

    ...

    items: [{ 
            xtype: 'mainapp-component1'
        },{
            xtype: 'mainapp-component2'
    }]
});

Ext.define('MainApp.view.component1.Component1', {
    extend: 'Ext.panel.Panel',
    xtype: 'mainapp-component1',    
    controller: 'component1',

    ...

    items: [{
        xtype: 'button',
        cls: 'contactBtn',
        scale: 'large',
        text: 'Fire Event',
        handler: 'onComponentButtonTapped'
    }]
});

Ext.define('MainApp.view.component2.Component2', {
    extend: 'Ext.panel.Panel',
    xtype: 'mainapp-component2',    
    controller: 'component2',

    ...

    items: [{
        xtype: 'textfield',
        value: 'Button is not clicked yet',
        width: 500,
        readOnly: true
    }]
});

*********** Controllers ***********

Ext.define('MainApp.view.component1.Component1Controller', {
    extend: 'Ext.app.ViewController',

    alias: 'controller.component1',

    onComponentButtonTapped: function (btn, eventArgs) {
        this.fireEvent('component1ButtonTapped', btn, eventArgs);
    }
});

Ext.define('MainApp.view.component2.Component2Controller', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.component2',
    listen: {
        controller: {
            'component1': {
                component1ButtonTapped: 'onComponent1ButtonTapped'
            }
        }
    },

    onComponent1ButtonTapped: function(){
        this.getView().down('textfield').setValue(Ext.String.format('Button tapped at {0}', Ext.Date.format(new Date(), 'Y-m-d H:i:s')));
    }
});

有人可以建议正确解决此案例的方法。

更多详情

选项卡面板在视口中加载

Tab 1 has first instance of Main Component  - M1
Tab 2 has second instance of Main Component - M2

主要组件的每个实例都有两个子组件

Component1 - M1C1 > M1C1 View and M1C1 Controller
Component2 - M1C2 > M1C2 View and M1C2 Controller

类似于主要组件的第二个实例

Component1 - M2C1 > M2C1 View and M2C1 Controller
Component2 - M2C2 > M2C2 View and M2C2 Controller

此处要求限制对M1C1视图执行的操作应仅由M1C2控制器处理。

Issue is that with the code above M2C2 Controller also listens to the event

2 个答案:

答案 0 :(得分:0)

handler: 'onComponentButtonTapped'更改为

{
    xtype: 'button',
    cls: 'contactBtn',
    scale: 'large',
    text: 'Fire Event',
    listeners: {
        click: 'onComponentButtonTapped',
        scope: SCOPE-YOU-WANT
    }
}

答案 1 :(得分:0)

首先,我相信您在MainApp.view.main.Main组件中覆盖过多,并且您也不使用布局进行覆盖。这可能导致不必要的后果,例如额外的布局运行和过大的DOM影响性能。

好,问你一个问题!我认为范围不是您在这里真正想要的。我认为这是如何正确构建ViewControllers。虽然这不是您的真实代码,但我会说在此示例中,您不需要该Component1Controller控制器。摆脱它,按钮的处理程序将解析到maincomponent控制器上,在这里您可以控制两个子项。我只说这完全知道您的Component1Controller可能正在做其他事情,所以这并不是说并不是所有容器都需要控制器。如果Component1Controller坚持下去,它也可以满足我在这种情况下的工作。与在Component1Controller实例上触发事件并使用事件域到达Component2Controller相反,我将在Component1上触发视图事件并在配置对象上添加侦听器,以便{ {1}}控制器获取事件来完成任务。

这听起来很混乱而且很难理解,所以我创建了这个fiddle