From the very beginning the Ext JS framework has implemented a class system to extend JavaScript. The goal of the class system was to support efficient code organization and implement a pseudo-classical inheritance found in many Object Oriented programming languages.
With the release of Ext JS 4.0, Sencha decided to revisit their class system and enhance it with more object oriented goodies. In particular they developed a config system, their answer to properties. This blog post will dive into the config system and how it is used in Ext JS 4.x, 5.x and Sencha Touch 2.x.
TL;DR on the Sencha Class System
The Sencha class system is the foundation of the entire framework family, beginning with a class known as Ext.Base. With only a few exceptions, classes must follow a particular naming convention directly related to their file path.
Here is a sample Sencha class definition, instantiation and usage: View on Fiddle
// Define class with name "Car" Ext.define('Car', { // Define config properties config : { make : undefined, model : undefined }, // First method that gets called upon class instantiation constructor : function (config) { // Initializes config properties this.initConfig(config); }, // Define drive method drive : function () { console.log('Driving ' + this.getMake() + ' ' + this.getModel()); } }); // Instantiate class "Car" with config properties var car = Ext.create('Car', { make : 'Honda', model : 'Accord' }); // Call method "drive" on class instance // Outputs "Driving Honda Accord" to the console car.drive();
The Config System
You may notice that we defined a couple of config properties in that class example. Let’s dive into what happens under the hood. The JavaScript interpreter treats the function argument as a plain object with a key “config” and it has a couple of child members. However, during the class instantiation process the method initConfig is called. As described, it initializes the config system for that class instance. The config system then registers the associated property config methods with the class instance.
Config Methods
Getter
Standard accessor method that returns the current value of the property. This is an auto-generated function by the config system. View on Fiddle
car.getMake(); // returns “Honda”
Setter
Mutator method that sets the value of the property on the class instance. This is also an auto-generated function by the config system. View on Fiddle
car.setMake(“Toyota”); car.getMake(); // returns “Toyota”
Applier
This function gets called by the setter when the configuration property changes (e.g. goes from undefined to “Foo”). The applier must return a value; this value will be the new value of the configuration property. The applier is auto-generated by the config system and is generally overridden to execute some kind of logic before setting the value.
// Example applier definition applyMake : function (newValue, oldValue) { // Execute some arbitrary logic if(oldValue.length > newValue.length) { return oldValue.toUpperCase(); } return newValue.toUpperCase(); }
Updater
The updater function gets called by the setter after the applier when the value for the configuration changes (e.g. going from “Foo” to “Bar”). The updater is generally used by a class as a reaction to a config property changing.
// Example updater definition updateModel : function (newValue, oldValue) { if(newValue === 'Accord') { this.setMake('Honda'); } else if(newValue === 'Camry') { this.setMake('Toyota'); } }
Potential Scenarios
- Change a UI element of a component based on a property change. View on Fiddle
// Enable Drive button if make is set applyMake : function (newValue, oldValue) { if(newValue) { this.down('button#drivebutton').enable(); } return newValue; }
- Instantiate a required dependency once a config value is set.
Example: instantiate and/or load a Store if a URL is passed to class. View on Fiddle
// Instantiate a store if "storeUrl" config property is set applyStoreUrl : function (url) { if(url) { this.setStore(Ext.create('Ext.data.Store', { fields : ['name'], proxy : { type : 'ajax', url : url, } })); } return url; }
- Instantiate a child class based on a config value.
Example: add a toolbar to a Panel. View on Fiddle
// Instantiate Ext.Toolbar with config and return class instance applyHeaderToolbar : function (cfg) { if(cfg) { var tbar = this.tbar = Ext.create('Ext.Toolbar', cfg); return tbar; } }
Ext JS 4 vs Ext JS 5 vs Sencha Touch 2
Even though Ext JS 4, 5 and Sencha Touch 2 share the same class system there are some differences regarding the role of the config system in the frameworks.
- In Ext JS 4 the config system took the back seat. Quite frankly it was rarely (if ever) used by the framework itself. Therefore many developers overlooked its existence all together.
- In Ext JS 5.x, Sencha began integrating the config system into its framework. Ext JS now initializes the config system at the Component level. With this, all components utilize config properties instead of object properties. A new feature of in the Ext JS 5 config system is that custom setters can now callParent to the automatically generated setter by the class system.
- Sencha Touch 2 was a major paradigm shift from its predecessor. This allowed Sencha the flexibility to start from scratch and do things “right”. What this meant in terms of the class system, was to enforce the config system throughout the entire framework. Sencha Touch 2 requires you to use the config system to manipulate class properties. It internally leverages the system to its full potential.
In summary, Ext JS 4 and Sencha Touch 2 can be considered the extremes of config system integration. Ext JS 5 sits somewhere in between due its backwards compatibility with Ext JS 4.
Related Reading
- Sencha’s Guides on the Class System:
— http://docs.sencha.com/extjs/5.0/core_concepts/classes.html
— http://docs.sencha.com/touch/2.4.0/#!/guide/class_system
— http://docs.sencha.com/extjs/4.2.2/#!/guide/class_system - Sencha Touch in Action (2nd Edition)
- The source code to Ext.Base and Ext.Class. These are my personal favorites as they give you the most insight on what truly is happening under the hood.
Stan Bershadskiy
Related Posts
-
How To Use Sencha Ext.Config
In a previous post, my colleague Stan explained the foundation of the Sencha Config System…
-
How To Use Sencha Ext.Config
In a previous post, my colleague Stan explained the foundation of the Sencha Config System…