Javascript Inheritance Basics
Posted on | August 17, 2008 |
I recently had the pleasure of writing a small AJAX application library based around/wrapping Ext JS.
Due to the requirements and the way the original application was devised, I needed to always make sure I pass a specific parameter on every AJAX request.
Here’s how I did it using my version of JavaScript prototypal inheritance (it may or may not be the right way to go about it, but it works for me).
One thing to note is I did wrap a lot of the Ext functionality, for future proofing really, so if some developer comes along and isn’t an Ext fan, then they can change the base library without changing code throughout the application.
The Javascript Parent Class
First we set up our base library to perform the common functionality needed by the application,
including making the AJAX request.
var MyApp = function() {
var version = 1;
// private members and methods
var _insertModule = function(moduleName) {
// ...
}
/**
* Common param needed through the application
*
* @param int programId
* @access private
*/
var _programId = null;
return {
/**
* Accessor set.
*
* @access public
*/
setProgramId : function(int_id) {
_programId = int_id;
},
/**
* Accessor get.
*
* @access public
*/
getProgramId : function() {
return _programId;
},
loadIcon : '/images/icons/icon-loader.gif',
/**
* Wraps Ext.Ajax to allow changing of Libs in need be.
*/
Ajax : function(config) {
return Ext.Ajax.request(config);
},
fromJSON : function(data) {
return Ext.util.JSON.decode(data)
},
toJSON : function(data) {
return Ext.util.JSON.encode(data);
}
};
};
So that’s the foundation for the application library. Like I said It wrap Ext so any developers who want to switch it for YUI or JQuery need only change the base file.
These examples don’t do much really, I’ve obviously trimmed out a large amount of code so it fits on the blog page!
Using the prototype property to extend the base class
The class that will extend the base will be a small class representing the notes or email section of my application.
The function documented sends a request to the server in the event when a user clicks to mark a note as read.
MyApp.Note = {
/**
* Marks a note as read.
* @param int note id
* @param int page id
* @param img (optional image parameter)
*/
markAsRead : function(note_id)
{
if(confirm('Are you sure you would like to mark this note as read?'))
{
// set to spinner temporarily.
//this.Get('note_icon_' + note_id).dom.src = this.loadIcon;
this.Ajax({
url: '/messaging/note_mark/' + page_id + '/',
method :'get',
params : {
'note_id' : note_id
},
success: function(http_response)
{
// change the icon to an open envolope to indicate as read...
alert('success');
// handle the response...
},
failure: function(http_response)
{
// handle the failure
}
});
}
}
};
// IMPORTANT!! we set the prototype to the base object.
MyApp.Note.prototype = MyApp;
So as you see we set the prototype to the base object, that means that the this keyword now has access to all the methods of the Base object. Cool eh?
I’ve tried to think of this as typical class like inheritance, but you can’t, the best way to think of it is static classes extending static classes just with this thrown in for good measure
So what’s the benefit?
Well this meant in my case I was able to hijack the parameters of the Ajax request and inject some new ones before it was sent to the server. So my new Ajax method looks like this:
/**
* Wraps Ext.Ajax to allow changing of Libs in need be.
*/
Ajax : function(config) {
if(!config.programId)
{
config.programId = this.getProgramId();
}
// debugging? force GET requests
//config.method = 'GET';
return Ext.Ajax.request(config);
},
Howaaazattt?!?!
Leave a comment if you’re unsure whats going on here and I’ll try my best to explain it.
Douglas “the man” Crockford also has a great piece on his way of dealing with the lack of classes in JavaScript. See his piece here
Comments
Leave a Reply