Product Update: Ext JS 8.0 is Coming Soon! Learn More

Using Sencha Ext.Config

August 10, 2016 4743 Views

Get a summary of this article:

Show

Guest Blog Post

In a previous article, my colleague Stan explained the foundation of the Sencha Config System and how the getters and setters work. In this post, I’m going to explain the new Ext.Config features that are available in Ext JS 6. You can also learn more by reading the Ext JS 6 docs.

Config All The Things

Ext.Config.cached

When set as true, the config property will be stored on the class prototype once the first instance has had a chance to process the default value.

config: {
    foo: {
        $value: 42,
        cached: true
    }
}

You can find a basic example in this Fiddle, and look at the following gif:

Cached Configs

An implementation can be found in Ext.util.ElementContainer.childEls property. Caching childEls into the prototype saves memory. Some CPU cycles are also saved in the configuration phase during class instantiation.

childEls: {
    $value: {},
    cached: true,
    lazy: true,

    merge: function (newValue, oldValue, target, mixinClass) {

Checking for cached configs is easy by accessing the cachedConfigs property through the getConfigurator() method:

myObj.self.getConfigurator().cachedConfigs

This is possible because of the Ext.Configurator utility class, which is instantiated the first time you call the getConfigurator() for a specific class.

Ext.Config.evented

If this is set as true, the config property will be treated as an Ext.Evented. This means that whenever the setter of this config is called, Ext JS will automatically fire an event [configname + change]. Note that you have to include the Ext.mixin.Observable mixin and call its constructor in the defined class constructor to initialize the mixin.

Ext.define('MyClass', {
    mixins: ['Ext.mixin.Observable'],
    config: {
        foo: {
            $value: 42,
            evented: true
        }
    },
    constructor: function(config) {
        console.log('MyClass Instantiated');
        this.initConfig(config);
        this.mixins.observable.constructor.call(this, config);
        return this;
    }
});
myObj = new MyClass();
myObj.on('foochange', function() {
   console.log(arguments);
});

You can find a basic example in this Fiddle and look at the following gif:

Evented Configs

Another way of defining evented configs is by using the eventedConfig of the Ext.Evented class, which is processed in onClassExtended phase:

Ext.define('MyEventedClass', {
    extend: 'Ext.Evented',

    eventedConfig: {
        boo: 34
    },
    constructor: function(config) {
        this.initConfig(config);
        this.mixins.observable.constructor.call(this, config);
        return this;
    }
});
myEventedObj = new MyEventedClass();
myEventedObj.on('boochange', function() {
    console.log('boochange');
    console.log(arguments);
});

The defined class has to extend the Ext.Evented to create the evented configs. An implementation of this approach can be found in the Ext.Widget.width property.

Ext.Config.lazy

If a lazy config is set as true, the config property will not be immediately initialized during the initConfig call.

   config: {
        foo: {
            $value: 42,
            lazy: true
        }
    }

You can find a basic example in this Fiddle and look at the following gif:

Lazy Configs

An implementation can be found in Ext.app.Application.mainView property where the mainView is created lazily. So performance-wise, it’s created when it’s used, not when the app is instantiated.

Ext.Config.merge

The merge config accepts a function which will be called as instances are created or derived classes are defined. The merge function accepts the new values and the inherited value and returns the combined config value. On further calls that returned value will be provided as oldValue through an argument:

Ext.define('MyClass', {
    config: {
        foo: {
            $value: [42],
            merge: function(newValue, oldValue) {
                var val = [].concat(newValue, oldValue);
                return val;
            }
        }
    },
    constructor: function(config) {
        this.initConfig(config);
        return this;
    }
});

Ext.define('MyExtendedClass', {
    extend: 'MyClass',
    foo: [23]
});

var myObj = new MyClass({
    foo: 123
});
//MyClass.foo:  – [123, 42]

var myExtendedObj = new MyExtendedClass({
    foo: 321
});
//MyExtendedClass.foo:  – [321, 23, 42]

You can find a basic example in this Fiddle and look at the following screenshot:

Merged Configs

An implementation can be found in Ext.panel.Header.title property where the merge config is used for merging a given title config with the default one:

title: {
    $value: {
        xtype: 'title',
        flex: 1
    },
    merge: function(newValue, oldValue) {
        if (typeof newValue !== 'object') {
            newValue = {
                text: newValue
            };
        }
        return Ext.merge(oldValue ? Ext.Object.chain(oldValue) : {}, newValue);
    }
}

Also, you could use the Ext.Config.mergeSets method to do your merges:

twoWayBindable: {
    $value: null,
    lazy: true,
    merge: function (newValue, oldValue) {
        return this.mergeSets(newValue, oldValue);
    }
}

Conclusion

Ext JS provides a lot of components and an easy way to extend them or build new ones. The Config System has a big role in achieving that, and it’s a core part of the framework. Besides that, it’s the best and most powerful Config System we’ve seen in a framework. If you’re working on your custom components, check out these suggestions and let us know how you used the configs.

Recommended Articles

Why JavaScript UI Components Matter More in Complex Frontend Architecture

What This Article Covers Why UI components matter – In complex frontend architecture, reusable JavaScript UI components help manage scale, improve performance, and ensure consistency…

Custom vs Prebuilt JavaScript UI Components – Which Is Better for Enterprise

What This Article Covers Build vs. Buy decision – Whether to build custom JavaScript UI components, use open-source libraries, adopt commercial solutions, or follow a…

How a JavaScript UI Framework Reduces Frontend Complexity

Frontend development has become dramatically more sophisticated over the last decade. What once involved a few scripts and styled pages has evolved into the engineering…

10 Common UI Pain Points in Large-Scale JavaScript Applications

At a small scale, many frontend decisions appear harmless. A team may: create a custom component quickly skip accessibility for one release add a one-off…

Common Responsive Design Challenges in Enterprise Web Applications

Modern businesses run on software that must work everywhere – on a desktop monitor in a corporate office, on a tablet carried across a warehouse…

Why Enterprise UI Development Gets Complicated Faster Than Teams Expect

Enterprise UI development refers to designing and building user interfaces for business-critical software used by organizations, departments, regulated industries, and large operational teams. These applications…

View More