Beyond the Core

In my earlier post, I compared the new Ext Core JavaScript library with JQuery to demonstrate how close they are on core functionality. I explicitly kept the scope narrowed down to areas where the two libraries overlapped, and my conclusion was that both are winners but I prefer Ext Core since I use ExtJS and prefer the coding style.

In this post, I want to get in to demonstrating some of the features of Ext Core that are either coded differently from JQuery or that the base JQuery library does not implement. The excellent Ext.Core manual has more detail on all the functions, so I’ll just bring attention to some of cool functionality I like.

Base Class Enhancements

One feature that might be controversial for some developers is that Ext Core augments some of the base JavaScript objects to ensure some features are present across implementations and to add some useful helper methods. The JavaScript Augmentation section of the manual has details on all the enhanced methods. Function, Array and String are the three base objects that get augmented.

For example, the String object is augmented with a static format() method that essentially allows the String to function like a typical printf function:

var dest = 'World';
var greeting = 'Hello';
var msg = String.format('{0}, {1}!',greeting, dest);
// msg contains "Hello, World!"

The Array object is augmented with indexOf() and remove() methods, and the Function object itself picks up several OO-centric functions.

The reasoning behind the augmentations are in the manual. I have mixed feelings on augmenting the language’s base objects, but the features are appreciated.

Namespaces

Using a namespace mechanism so that all your variables don’t pollute the global namespace is something every JavaScript coder should be doing. There are plenty of code snippets out there to demonstrate how this is done, but Ext Core makes it easy for you by including namespace support as a part of the library. All this is handled through the Ext.namespace() static method.

Take a look at the sample below. The comments indicate the filenames:

// first.js
Ext.namespace('First');
First.name = 'Tim';

// second.js
Ext.namespace('Second');
Second.sayHello = function(name) {
    alert( String.format('Hello, {0}',name) );
};

// main.js
Ext.onReady(function() {
	Second.sayHello( First.name );
});

The three JavaScript files don’t even need to be imported in this order. Everything happens through the namespace references declared at the tops of the files and managed by Ext Core. In this case, objects called First and Second were created under window, and the sayHello method and ‘name’ variable were placed under them. This means our code only added two variables to the global space. This didn’t make a difference with only two variable declarations, but can have a huge impact with a typical application.

Namespaces can be hierarchical, so you can limit the global pollution to a single entry. For example, you can define a namespace like this:

Ext.namespace('Application.Init');

Ext Core will create all the intermediate namespaces, so you could places variables under both Application.Init and Application with this single declaration. This provides a similar naming hierarchy to what you would find in Java packages or C# namespaces.

Encode and Decode

Ext Core provides helper methods to encode and decode both JSON and URL-encoded data. The Ext.encode and Ext.decode will encode or decode JSON objects to and from Strings. This is useful for the AJAX methods, as I demonstrated in my other post. In the current beta, the encode and decode methods aren’t implemented yet, but they are in the documentation, so I’m expecting to see them before the final release.

The Ext.urlEncode and Ext.urlDecode methods will encode or decode JSON objects to URL-encoded strings. One typical example is to decode query string parameters. For example, if the page URL was this: http://mycoolapp.com?name=Tim&lang=Java, you could easily decode the query string into a JSON object using this snippet:

var params = Ext.decode( document.location.search.substr(1) );
alert( String.format('Hello, {0}', params.name) );

Yes, this is a bit of a hack. I didn’t do error checking to ensure there was a value for search before using substr(). The substr() is necessary when working with a query string because the search value will start with a question mark (?), which the Ext.urlDecode method won’t strip off.

Templates

Ext Core thankfully includes Templates, a feature generously carried down from ExtJS. Templates simplify the repetitive generation of HTML fragments, which is something that typically happens in AJAX intensive web application. The Ext.Template class allows you to define an HTML fragment as a template, using tokens which will be replaced with the values from a JSON object. For example, here is a code sample of a Template used to format an RSS feed from Slashdot that I turned into a JSON object:

// Feed.data is an array of JSON objects that look like this:
// {title: 'title', link: 'link', description: 'description'}

var template = new Ext.Template(
            '
', '

{title}

', '{description}', '
'); // stories is the id of the empty div on the page var stories = Ext.get('stories'); Ext.each(Feed.data, function(item) { template.append(stories, item); });

This snippet also demonstrates the Ext.each() helper method for iterating over the contents of an array. You can download the full snippet here to play with.

As Ext Core is still in beta, there is a disconnect between the API documentation and the actual implementation. If the Ext.Template class is updated to correspond to the documentation, there are also some neat formatting effects that can be applied. For example, instead of the placeholder {description}, you could use {description:ellipsis(20)} which will truncate any string longer than 20 characters and place ellipsis at the end of the string.

I’ve covered a few of the cool features to make your JavaScript code easier and more maintainable. Ext Core also has some neat OO functionality that I’ll cover in another post.

Leave a Reply

Your email address will not be published. Required fields are marked *


*