How to Use Global Functions and Variables

Sencha

Best practice will tell you global functions and variables can be bad, in some cases being pushed as “extremely” bad leading you to potential problems further down the road. but there are some cases where global functions and/or variables are exactly what solves the problems best.

Ext JS being a fantastic framework is no exception to those who advocate against solving problems using global.

When the time finally comes to realize a global is the best way to your solution you will encounter the difficult search of good examples how to implement them.

One advantage of global definition is when creating variables Ext JS creates both a getter and setter. Take the code in globalFunctions.js

Ext.define('globalFunctions', {
    // Singleton is a popular design pattern in OO languages where a class configured
    // to be singleton has only one instance throughout the application.
    // Configured as singleton, an instance is automatically created.
    // Ext.create('globalFunctions') would generate an instantiation error
    singleton: true,
    // Allows us to call this class without using the full name spec in more
    // controlled production environments
    alternateClassName: 'globalUtils',

    // config lets us define variables with access from this class
    // doing so creates both getter and setter for the variable
    config: {
        userName: 'Andy Allord - Sencha MVP',
    },

    constructor: function (config) {
        this.initConfig(config);    // Initialize config to make variables available
        this.callParent([config]);  // Initialize on parent
    },

    changeUserName: function () {
        // For demo this is self contained. In a production environment it is best
        // to place the dialog definition into a separate file.
        let wdw = Ext.create('Ext.Dialog', {
            title: 'Change User Name',
            padding: 10,
            width: 400,
            height: 200,
            bbar: [{
                xtype: 'button',
                text: 'Change Name',
                iconCls: 'x-fa fa-save',
                handler: function (btn) {
                    // Uses global setter to set userName global variable
                    globalUtils.setUserName(wdw.query('#tfNewUserName')[0].getValue());
                    Ext.ComponentQuery.query('#dfGlobalVar')[0].setValue(globalUtils.getUserName());
                    btn.up('dialog').close();
                }
            }, {
                xtype: 'button',
                text: 'Cancel',
                iconCls: 'x-fa fa-ban',
                handler: function () {
                    wdw.close();
                }
            }],
            items: [{
                xtype: 'textfield',
                itemId: 'tfNewUserName',
                label: 'New User Name',
                anchor: '100%'
            }]
        });
        wdw.show();
        Ext.ComponentQuery.query('#tfNewUserName')[0].focus();
    },

    getTestAve: function () {
        let tot = 0;
        // Uses the arguments array so any number of test scores can be sent
        for (let x = 0; x < arguments.length; x++) {
            tot += arguments[x];
        }
        // Format number to 2 decimal places in the returned result
        return Ext.util.Format.number(tot / arguments.length, '0.00');
    }
});

Under the config definition there is the variable userName. This variable has both a getter and setter created. A little further down you will see how this streamlines and creates a flow to change values in the right places and now is available in all your code.

Ext.application({
    name : 'Fiddle',

    requires: [
        'globalFunctions'
    ],

    launch : function() {
        let pnl = Ext.create('Ext.Panel', {
            padding: 10,
            items: [{
                xtype: 'displayfield',
                itemId: 'dfGlobalVar',
                label: 'Global Variable userName',
                // Use global getter for defined variable userName
                value: globalUtils.getUserName()
            }, {
                xtype: 'displayfield',
                label: 'Calculated Test Average getTestAve(100, 84, 73, 93, 64, 53, 31)',
                // Send to global function to set the value of this display field
                value: globalUtils.getTestAve(100, 84, 73, 93, 64, 53, 31)
            }, {
                xtype: 'button',
                text: 'Change User Name',
                iconCls: 'x-fa fa-plus',
                handler: function () {
                    globalUtils.changeUserName();
                }
            }, {
                xtype: 'button',
                text: 'Get User Name',
                iconCls: 'x-fa fa-arrow-down',
                handler: function () {
                    Ext.Msg.alert('Global User Name', 'User Name: ' + globalUtils.getUserName());
                }
            }, {
                xtype: 'displayfield',
                margin: '20 0 0 0',
                label: 'Demonstrated by Andy Allord - Sencha MVP'
            }]
        });
        Ext.Viewport.add(pnl);
    }
});

As you can see in the actual application the global variable is displayed, a button is given to change the user name using the generated setter and then a button is used to call the generated getter.

Another display field calls the global function getTestAve(), passing a variable length array by using JavaScript arguments being passed with every function call.

So now we have a means to create global functions and variables to use in those instances applications get large enough and some functions/variables simply need to be available to more than a single class.

You can find a working demo on Sencha Fiddle here.

Share:

Author: aallord

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.