Dynamic Sub-classing a parent class.
I'm going to spend my time talking about two functions: extend and override. This first, extend, is used to subclass at runtime. I find this behavior pretty impressive, but of course, so is the JavaScript language.
extend : function(){
// inline overrides
var io = function(o){
for(var m in o){
this[m] = o[m];
}
};
return function(sb, sp, overrides){
if(typeof sp == 'object'){
overrides = sp;
sp = sb;
sb = function(){sp.apply(this, arguments);};
}
var F = function(){}, sbp, spp = sp.prototype;
F.prototype = spp;
sbp = sb.prototype = new F();
sbp.constructor=sb;
sb.superclass=spp;
if(spp.constructor == Object.prototype.constructor){
spp.constructor=sp;
}
sb.override = function(o){
Ext.override(sb, o);
};
sbp.override = io;
Ext.override(sb, overrides);
return sb;
};
}()
This function is documented as taking a "class inheriting behavior", a "class being extended" and an optional "literal with override members". I'll be a bit ADD here with my description. I may come back and clean it up, but here we go.
First of, let's talk about the io function. This is an inline version of Ext's override function. This function is responsible for replacing one object's methods with another's. This is done through method name.
Example ext usage:
var MyGridClass = Ext.extend(Ext.GridPanel, {
constructor: functon(){...},
myFunc: function(){ alert('Hai Wurld!'); }
});
var myGridInstance = new MyGridClass({ ...config...});
Now to the meat of the function:
The first thing the function does is test to see if it's a two argument or three arugment function. If it's only two arugment, then a "subclass" parameter has not been defined, so variables are maniuplated for this.
Next it creates a few local variables: F -> "null" function, sbp -> sub-class prototype (undefined), and spp -> super-class prototype (sp.prototype).
The next thing that happens is assigning F's prototype to be spp. This effectively makes F be a sub-class of the super class (i.e. var o = new F(); o.prototype.prototype == spp).
The next thing is a little assignment magic. The local variable sbp is assigned to the *old* subclass prototype, while the new sub-class prototype is assigned to "new F()". The sub-class now has F as a super-class. After that, we re-wire the sub-classes constructor and superclass. There's a little magic here to handle constructors. This is sort of Ext-specific as I understand it. (Meaning your constructor won't be called unless you're extending an Ext Component). Ext then ensures that each subclass contains an "override" method on it by placing a localized implementation of the override function on the subclass. The last thing the function does is apply the optional overrides object to the new subclass.
So, the description might be a little hazy, and that's due to my hazy understanding of some of the steps. I'll try to fill in a better description the more I grasp it. The point I wanted to get across was the F variable becoming a new Parent in the sub-class's hierarchy. Ridiculously cool behavior, and thank you Ext for giving me an implemnetation so I don't need to fry my brain thinking of how to do it myself!
Ext-Bridge: Choose your Ajax
Ext allows you to choose an underlying library. Ext 2.0.1 provides adapters for the following libraries: Yahoo! UI, Prototype/Scriptaculous and JQuery. Ext also has a home-grown solution for AJAX calls (that works great).
What is the bridge actually for? Well, I started perusing some of the adapter code to figure out what the adapter actually does and why I would want to use it. From what I can make out, Ext delegates certain functionality to an underlying library. If the library can't perform said functionality, then it provides its own implementation. Classic Bridge pattern.
So what does Ext pass through the bridge? I tried to compile a list.
- Ajax requests (form-based and non-form-based)
- Event Handling (Registering, propagation, scope and translations)
- Animations
- 2D Geometrical Mathematics (For UI rendering)
- Dom Queries
- Element Locations
The good news is this. If I really like the Jquery interface (which I do. It's one of the coolest feeling APIs I've seen), then I can make use of the API and still use Ext. Not only that, if I wanted to add a listener to ALL ajax requests, I can do so using the JQuery api, and I will get not only requests made with the JQuery API, but also those made with the Ext API. It really makes using two libraries easier.
Also, if I like the Scripaculous effect more than Ext effects, I can pull in the Ext-Prototype/Scripatculous bridge and make use of them. Then I don't have to give up my Prototype knowledge to start using Ext. I can use them together.