Ajax ServiceA history of my evolution in ajax, I begin at adoption of prototype. Here the Ajax.Request was all powerful but, its syntax, i felt became redundant in most applications. I then create Ajax.Application, which soon became Ajax.Application.Base as its subclasses, Ajax.Application.Cache and Ajax.Application.Queue soon proved to have their own niche in my repertoire. I started off using these classes to inherit my "Ajax Applications" from, these classes would manage DOM elements and coordinate DOM Events with dispatching XHR requests and handle all appropriate updates to these DOM elements to provide user experience. This works, but a major drawback is that this all goes on inside the black box of the class. Another spectrum, an EventOn a totally different branch of development I created a class to mimic event propogation. This worked out great for allowing communication between classes. A simple example would be a "List" class which could govern a list and then dispatch a "itemClick" event if any of the list items were clicked. Greed lead to MarriageSoon I wanted the advantages of both, dispatch events and the sweet syntax of Ajax.Application, I did something I know is a fopah of programming but since the classes don't inherit from anything themselves I merged them. EventDispatcher and Ajax.Appication.Base into Ajax.Application.Event. The results were fantastic, allowing many components respond to eachother ajax requests was great but things got sloppy. The new model, a ServiceThat is when i got the idea to seperate all DOM management from the class that will be interacting with the server. Then dispatch the event, being the XHR "transport" for us prototype junkies to all observing functions of the event. In this manner we have completely decoupled interface management for the class responsible for XHR requests. Now classes can be written with the complete ignorance of all other things but the fact that this particular function is designed to receive that object. Caution, Service at work below
Above is my attempts at demonstrating a simple service, I have one action in myservice, which is to receive a number from the server. I have 4 interface components which are looking to do something with that number, Main simply displays the number, the rest are respective to their operation in mathematics. The ServiceAjax.Application.Event serves as the base class for the services, I have named this one Service but I am sure to have a more flexible naming convention soon. So the service creates a listener which is a function closure around the handling function. The getNumber function is the actual execution of the service. In my real implementations these action functions typically receive a hash object, which works great with forms and Form.serialize(true).
var Service = Class.create();
Object.extend(Object.extend(Service.prototype, Ajax.Application.Event.prototype),
{
initialize : function(url){
this.url = url;
this.createListener();
},
createListener : function(){
this.receiveNumberHandle = this.receiveNumber.bind(this);
},
getNumber : function(){
this.sendRequest({ action : "getNumber"}, this.receiveNumberHandle);
},
receiveNumber : function(eAja){
this.dispatchEvent("receiveNumber", eAja);
}
}
);
The Base ListenerAll 4 of my interface components are going to share very similar traits so I abstracted these into a base class called ServiceListener.
var ServiceListener = Class.create();
Object.extend(ServiceListener.prototype,
{
buildInterface : function(obj){
this.container = $(obj);
},
createListener : function(){
this.receiveUpdateHandle = this.receiveUpdate.bind(this);
},
receiveUpdate : function(eAja){
var obj = eAja.responseText.evalJSON();
this.update(obj.number);
},
update : function(num){
throw { message : "Overwrite this method in subclass" }
}
}
);
Ladies and Gentlemen...The Implementations
var Addition = Class.create();
var Multiply = Class.create();
var Factorial = Class.create();
var Main = Class.create();
Object.extend(Object.extend(Addition.prototype, ServiceListener.prototype),
{
initialize : function(obj){
this.buildInterface(obj);
this.createListener(obj);
},
update : function(num){
this.container.innerHTML = num + num;
}
}
);
Object.extend(Object.extend(Multiply.prototype, ServiceListener.prototype),
{
initialize : function(obj){
this.buildInterface(obj);
this.createListener(obj);
},
update : function(num){
this.container.innerHTML = num * num;
}
}
);
Object.extend(Object.extend(Factorial.prototype, ServiceListener.prototype),
{
initialize : function(obj){
this.buildInterface(obj);
this.createListener(obj);
},
update : function(num){
var sum = this.factorial(num);
this.container.innerHTML = sum;
},
factorial : function(num){
if(num == 1)
return num;
else
return num*this.factorial(num-1);
}
}
);
Object.extend(Object.extend(Main.prototype, ServiceListener.prototype),
{
initialize : function(obj){
this.buildInterface(obj);
this.createListener(obj);
},
update : function(num){
this.container.innerHTML = num;
}
}
);
Class OverSo thats the overhead of classes which would be in the library. Linking everything together is pretty simple. As of now I have some pretty specific functions I think it would be better to have a higher level class manage a collection of objects and only spit out bigger events. Check out the demo and feel free to check out the source to make sure im not BSing, the code displayed in the <pre> tags is identical to what you'll find in the <script> tags.
var myService = new Service("javascript-service.php");
Event.observe("myButton", "click", function(){ myService.getNumber() });
var myMultiply = new Multiply("multiply");
var myFactorial = new Factorial("factorial");
var myAddition = new Addition("addition");
var myMain = new Main("main");
myService.addEventListener("receiveNumber", myMultiply.receiveUpdateHandle);
myService.addEventListener("receiveNumber", myFactorial.receiveUpdateHandle);
myService.addEventListener("receiveNumber", myAddition.receiveUpdateHandle);
myService.addEventListener("receiveNumber", myMain.receiveUpdateHandle);
|
||||||||||||||
CommentsNo comments have been posted for this page.
|
||