6
votes

I have a Panel and I need to capture/handle the mouseover event for the element of this panel.

Currently I do this by extending the ExtJS Panel with the following listener (as suggested here):

...

listeners: {
    mouseover : {
        element : 'el',
        fn : function(){
            console.log('captured mouseover');
        }
    }
},

...

Can it be done via the ExtJS controller? So that I have the event handling in one controller?

4

4 Answers

8
votes

You're on the right track, just not completely there yet. Controller's job is to control components not elements. If you want to make element's mouseover event to be available at the component level, just refire it as distinct 'mypanelmouseover' event and use that in Controller's control().
Nice and neat.

EDIT:

Here's how to do it:

Ext.define('My.Panel', {
    extend: 'Ext.panel.Panel',

    constructor: function(config) {
        var me = this;

        me.callParent(arguments);

        me.addEvents(
            'mypanelmouseover'
        );
    },

    afterRender: function() {
        var me = this;

        me.callParent();

        // Declarative style with listeners reads better,
        // but this is shorter and does the same
        me.mon(me.getEl(), 'mouseover', function() {
            this.fireEvent('mypanelmouseover')
        }, me);
    }
});

Ext.define('My.Controller', {
    extend: 'Ext.app.Controller',

    init: function() {
        var me = this;

        me.control({
            'panel': {
                mypanelmouseover: me.onMyPanelMouseover
            }
        });
    }
});

Hope this helps. The main idea is to keep being declarative and decouple your code instead of creating unreadable callback chain. A nice side effect is that you're in control and can decide which events you want to refire and when, and how to react to them.

4
votes

You could attach the listener after the component renders:

Ext.define('My.controller.A', {
    extend:'Ext.app.Controller',

    init: function(){ 
        this.control({
            'panel1':{
                afterrender: function(cmp){
                    cmp.getEl().on('mouseover', this.panel1_mouseOver);
                }
            }
        });
    },

    panel1_mouseOver: function(e, t, eOpts){
        alert('mouseover');
    }
});
2
votes

I think the only way to add that feature is to change the library's source for the Panel component. I don't think this is a good idea because it'll probably slow your site down with all the extra listeners, but this is how you'd do it.

http://docs.sencha.com/ext-js/4-1/source/Panel.html#Ext-panel-Panel Look for "me.addEvents" to see the events that ExtJS decided to give access to. You could add the mouseover event there, then add the listener in the controller.

What exactly are you doing for that listener? If you are just adding a class to the panel's div element then you could just use the overCls config http://docs.sencha.com/ext-js/4-1/#!/api/Ext.AbstractComponent-cfg-overCls

It looks like there are only a few components that support the mouseover event. Would it be possible to separate this mouse over functionality into a menu or button component?

1
votes

Every component has "getEl" method. Use this method to get Dom element and then register event on it.