Recently I started using ExtJS at work. I have to say that I really like it. They've done a great job at consistency and predictability. It's not perfect (what is really?) and I do a fair bit of fighting with it to make it do what I need. But, of the large JavaScript frameworks out there, I have to give my vote for the winner being ExtJS.
There was a key concept in ExtJS (and YUI and others I'm sure) that I hadn't given enough thought to in ZJS: events. The reason I had skipped over eventing in ZJS is its entanglement with the DOM and browser. The core features of ZJS ($class, $namespace, et.al.) do not require a browser. They are deliberately language-centric and can run in just about any JavaScript host. For example, I've tested ZJS core.js under Rhino and WSH (Window Script Host).
Well, ExtJS reminded me that I can implement events in a similar manner. It will be limited somewhat in environments that don't have asynchronous notifications flying about, but ExtJS had good use for events from its Store objects and grids. The Store would fire events whenever data was loaded, for example, which did not require any advanced features.
In ExtJS, the event source classes derive from Ext.util.Observable. This class provides the addListener (a.k.a. "on") and removeListener (a.k.a. "un") methods and many others as well. A class that publishes events does so like this:
foo.Bar = Ext.extend(Ext.util.Observable,
{
constructor : function ()
{
this.addEvents(
"beforechange",
"change"
);
}
});
This creates some minimal bookkeepping for each event which is expanded when (or if) a listener comes along. This helps keep the memory footprint down. There are two things that bother me about this approach for events.
- Events are 3rd class citizens in the object model. They are not added to a class like other pieces - rather a method of a specific base class does the work.
- Being defined on the instances and not on the class not only wastes memory but also means there is no data about events at the class level (without an instance).
Events should be treated similarly to the methods and properties of a class - ideally declared in some fashion. There should be no required base class to expose events. Events should be inheirtable and have zero per instance overhead (until a listener arrives). Lastly (for now), the mechanism should be extensible enough to support DOM events and their many quirks.
Here's the syntax I've settled on:
$namespace(foo,
{
Bar : $class(
{
$events :
[
"beforechange",
"change"
]
});
});
Next time I'll cover how the above syntax was implemented and how to make use of it.
No comments:
Post a Comment