I’ve been working with Ext JS a lot at work over the last year, and have grown to like it. Last year I went to the Sencha Conference in San Francisco, and was very impressed by the features of the upcoming release of Ext JS 4. One of the big changes is the new Class system, which makes defining classes easy and also loads required classes dynamically when required. The build tools which Sencha (The company which makes Ext JS) provides make it easy to produce a single compressed .js file of your app for deployment. All in all it is a great framework.
The Ext JS 4 class system lets you define a class as follows:
1 2 3 4 5 6 7 8 9
Obviously, the ‘constructor’ function is what becomes the class constructor. The ‘extend’ property will cause this class to inherit the given class. Note also the use of namespaces, eg ‘foo.Bar’ in the names of classes. In Ext JS 3 you had to explicitly declare all your namespaces, but in v4 this is handled automagically.
Mix it up with Mixins
Additionally, you can have ‘mixins’ which add in methods (or properties) of the given class. This is very helpful as it enables another way of re-using code besides inheritance. This is how you declare mixins (an example from Canvasteroids):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
The initDrawable(), beforeDraw(), draw(), and afterDraw() methods all come from the Drawable mixin class (which is defined in the same was a regular class except it does not have a constructor). Drawing is a behaviour, and this is a good use case for using a Mixin. As with inheritance, you can override methods or properties from a Mixin class. In this case I overrode the ‘draw’ method with a custom implementation. In this way Mixins can act like Abstract Classes, but you are free to use more than one at a time.
callParent() is super!
Also note the call to callParent() : this is equivalent to super() in ActionScript.. it calls the same method from which it is called on the parent class. So in a constructor it will call the super-class’s constructor. Note that the arguments must be passed as an array.
Getting Loaded with Ext.Loader
The ‘enabled:true’ attribute of the object passed to Ext.Loader.setConfig() is what turns on the dynamic loading of classes. When this is turned on, Ext JS will dynamically add a ‘script’ tag when it notices that it needs to load a class. By default, it will look for a file with the same name as the class (replacing ‘.’ with ‘/’) relative to the HTML file. If you wish to use a different path you will need to add a mapping to the ‘paths’ hash object. By default, the ‘Ext’ namespace is mapped to the ‘src’ directory of the library so it will load other classes from the framework if you are using them.
Then you load your main app using a call to Ext.require(). In this case I required the main Asteroids game class, which was in the same directory as the HTML file this code is in. The ‘Asteroids’ class itself has multiple dependent classes, and the Loader will recursively parse them until they are all satisfied.For example the ‘canvasutils.Context2D’ class will be resolved to ‘../../lib/canvasutils/Context2D.js’. NB: make sure you name your class correctly, or errors will occur in the loading process. In addition to any classes referenced in an ‘extends’ or ‘mixins’ definition, there is a ‘requires’ property which can be used to explicitly declare a class’s dependencies. For example in the Asteroids class, I have defined the requires as follows:
1 2 3 4 5 6 7
When the Loader is enabled, Ext JS will wait until all the dependent classes have been loaded before executing Ext.onReady(). At this point you can simply instantiate the class normally with ‘new’ as I have done. Alternatively, you can use Ext.create() with the class name as a string. This has the advantage that if for some reason the class was not loaded, the Loader will load the class synchronously. However, this is non-optimal for performance, and you will be warned in the console about this. Since I want to avoid this, and for ease of debugging, I tend to use the old fashioned form of instantiation with ‘new Xxx()’, and remember to add the class to the list of ‘requires’.
Note that the order of the classes in the ‘requires’ array does not matter.
Building a Deployment version
And you should have a app-all.js file which will be the combined and compressed version of your app. You should create another HTML file for deployment which references this file, rather than the Ext.Loader config we used for develpoment. That’s it! Your Ext JS 4 app is ready to go.
This is a brief overview of the Class system, for more info see the excellent docs: