Search code examples
extjsextjs4extjs4.1

Best practice adding KeyMaps to a Viewport


what's the best place to create / bind KeyMaps to a Viewport ?

Given a very simple Viewport like this :

Ext.define('EmptyTemplate.view.Viewport', {
    extend: 'Ext.container.Viewport',
    requires:[
        'Ext.layout.container.Fit',
        'EmptyTemplate.view.Main'
    ],
    layout: {
        type: 'fit'
    },

    items: [{
        xtype: 'app-main'
    }],

    listeners: {
        afterrender: {
            fn: function(){
                // map one key by key code
                this.keyMap = Ext.create('Ext.util.KeyMap', this.el, {
                    scope: this,
                    key: Ext.EventObject.ENTER,
                    fn: function () {
                        console.log("enter pressed");
                    }
                });
            }
        }
    }
});

Whats the proper way to create KeyMaps?


Solution

  • First some best practice advises:

    If you need to setup your component use

    • the [initComponent][1] (you should read this for detailed information),
    • the other provided template methods and
    • in some rare cases the constructor.

    In you case I would use the template method afterRender

    Ext.define('EmptyTemplate.view.Viewport', {
        extend: 'Ext.container.Viewport',
        requires:[
            'Ext.layout.container.Fit',
            'EmptyTemplate.view.Main'
        ],
        layout: {
            type: 'fit'
        },
    
        items: [{
            xtype: 'app-main'
        }],
    
        afterRender: {
            this.callParent(arguments); // always!!
            this.bindKeyMap();
        },
    
        bindKeyMap: function() {
            var me = this; // use 'me' if 'this' occurs more then 3 times
            if(me.keyMap) {
                me.keyMap.enable();
                return;
            }
            // map one key by key code
            me.keyMap = Ext.create('Ext.util.KeyMap', me.el, {
                scope: me,
                key: Ext.EventObject.ENTER,
                fn: me.onEnter
            });
        },
    
        unbindKeyMap: function() {
            this.keyMap.disable();
        },
    
        onDisable: function() {
            this.unbindKeyMap();
            this.callParent(arguments); // always!!
        },
    
        onEnable: function() {
            this.callParent(arguments); // always!!
            this.bindKeyMap();
        },
    
        onEnter: function(){
           // i am executed in the scope of the class instance
        }
    });
    

    Note that the example above handles the whole keymap but you can also add / remove single keys from the map.

    Note that this is untested prototype code, but it should work this way.


    How to find template methods:

    1. Go to the docs
    2. Show protected member

    enter image description here

    1. Look for the enter image description here mark

    enter image description here

    This post about overriding might also be a good reading