Archive for the ‘Your Questions’ Category

Singletons and Event Arbiters

June 23rd, 2009 by Aaron N.

I got an email today asking about how I use singletons in my own development environment and I thought I’d post my response for anyone who might find it useful.

Here’s the question:

Whats the best way to define some
code, assign it to a global object and have it run all at once?

I use MooTools server-side quite a bit in my ASP code using JScript
and we have need for global singleton objects to be around (such as
our logger). As there are no clear best practice ways out there of
doing it I’ve started and stuck with something like this:

var LoggerObject = function() {
// Logger code
}

var Logger = new LoggerObject()

which is ok but feels like I’m missing something. How do the pros do
it, whats the advantages/disadvantages to other methods?

Now, for those who aren’t familiar with the concept, a singleton is a class that designed to have only one (or, perhaps, a limited number greater than one) instance. In JavaScript, any object can inherit from any other object and you can’t really prevent this, so in the truest sense of the term, there’s no such thing as a JavaScript singleton.

MooTools gives us a function called “Class” which helps us manage inheritance between objects. Creating an object that is an instance of a class is done with the “new” operator:

var myWidget = new Widget()

If you wanted to create a class and immediately cast it into an instance, you could do the following:

var myInstance = new new Class({...})

The double “new” invokes the function returned by class and returns an object – an instance of that class. There’s rarely a reason to do this. In fact, the only reason I can think of is if you want that class to extend another:

var myInstance = new new Class({
    Extends: SomeOtherClass,
    //new properties go here
});

The problem with this pattern is that it doesn’t really get you much. JavaScript is all about objects, and there are better ways to accomplish this task.

I use objects (as singletons) all the time for my application code (almost never for plugins obviously; those are meant to be extended and instantiated). I often use a “site” object to attach methods and manage state (such as if the user is logged in, their username, etc). I just make this a plain old JavaScript object, like so:

var mySite = {
    login: function(username){ this.username = username; },
    showWelcome: function(){
        $('welcome').set('html', 'Welcome ' + this.username);
    }
};

There’s nothing special here – this is how JavaScript works. It’s important to note that classes in MooTools exist to give us functionality and to let us derive functionality through inheritance. If I create a class called Widget and I later want to make a version called Widget.Ajax, I can extend Widget and add only the ajax parts. With singletons, the whole point is that you aren’t going to create more than one of them.

However, there are some other things that MooTools’ Class gives us, such as mixins (classes that are meant to use Implement to imbue the target class with their properties). Examples here include the Events and Options mixins that give instances methods like setOptions and addEvent. In these cases you can still use the object declaration above and then extend the object:

var mySite = {
    login: function(username){
        this.username = username;
        this.fireEvent('login');
    },
    showWelcome: function(){
        $('welcome').set('html', 'Welcome ' + this.username);
    }
};
$extend(mySite, new Events());

Working this way obviates the need for the clunky “new new Class” pattern and it’s more intelligible in my opinion.

Event Arbiters

Which brings me to a common practice I use when I build applications. When I build a site or application I try to make things as modular as possible. I make it so that my site works without any JavaScript first, then I start adding in the UI goodness with ajax and animations and sortable tables and all that jazz. I also make the JavaScript itself modular. Everything that can be a class I make a class. The stuff that’s left over is the code that instantiates those classes.

But what if the code that instantiates one widget needs to get information from another widget? For instance, what if our Welcome widget needs to know the state of the Login widget? Well, if our Login widget stores it’s state on the mySite object, then the Welcome widget can just inspect that, right? That’s cool; if the page loads and mySite.username is undefined then the Welcome widget knows the user isn’t logged in. All good.

But what happens when that state changes? What happens when the user logs in? Now we need an event – onLogin or something, but that means that Welcome needs to attach itself to Login and now we’ve lost some modularity because we’ve introduced a dependency. Welcome can’t work without Login. In this case, this doesn’t seem like a bad dependency to have – after all, a welcome message without login functionality doesn’t make much sense – but there might be dozens of other widgets that need to do things when the user logs in and we may want those widget to work even if the user doesn’t log in. Further, we may want to load the Login widget only on demand – when the user tries to log in for example. We can’t do that if all our widgets need to attach events to the Login widget.

This is why I make mySite an instance of Events. mySite doesn’t really have any native events per se. Rather, other classes attach events to it and fire events for it. So, in our puzzle above about our Login widget, instead of all the other widgets attaching an onLogin event to Login, they can attach it to mySite, and then our Login widget fires that event not on itself but on mySite:

var mySite = new Events();
var Login = new Class({
    //...login logic and stuff
    loginSuccess: function(username){
        mySite.username = username;
        mySite.fireEvent('login');
    }
});
var Welcome = new Class({
    initialize: function(){
        this.showMessage();
        mySite.addEvent('login', this.showMessage.bind(this));
    },
    showMessage: function(){
        $('welcome').set('html', mySite.username ? 'Welcome ' + mySite.username : 'Please log in');
    }
});

Now our classes are no longer dependent on each other. They are both dependent on mySite but that was always the case. They can each come and go as they wish without really caring about the other. This increased modularity pays off later as your site grows in complexity. Some pages may have some widgets and some may have others. You can attach logic to the mySite object without having to really manage those dependencies.

jQuery vs MooTools, MooTools vs jQuery

May 18th, 2009 by Aaron N.

Every day on twitter I see posts where people are asking themselves the same question: MooTools or jQuery? This is because I have a saved search for “mootools.” Doing a search for “dojo” or “prototype” would find similar tweets from people considering those frameworks or jQuery. The fact is, jQuery is incredibly popular and it’s own popularity breeds adoption as much as the fact that it’s a good bit of software.

Focusing on the “MooTools or jQuery” question, it’s clear that there isn’t a great resource that helps people decide. Looking at the documentation and examples for the two libraries shows they share a lot of functionality. If you’re just now, in 2009, trying to decide which one of these frameworks you want to dive into first, chances are you’re probably relatively new to JavaScript itself and the prospect of comparing the frameworks by actually reading their source code is perhaps more effort than you want to spend. Were I in such a position, I’d want someone to do that for me; to look at them and tell me why some choose one over the other.

So, today I’m releasing jQuery vs MooTools which aims to do just that. No doubt this will cause a stir in our communities but hopefully it will be a healthy one.

I’m not trying to convince people who love jQuery that they’re wrong and should switch, nor am I trying to illustrate to the MooTools community what they’re missing from jQuery. This site is aimed at people who are trying to make this decision and is meant to be an honest comparison of the two libraries. It’s obvious where my bias lays – I’m a MooTools supporter. But I’ve tried to represent the two libraries fairly and, where my opinion is expressed, I try and call that out and say it’s just that – my opinion.

It’s entirely likely that I’ve misrepresented something about the jQuery core library in this post but I’ve done my best not to. Before publishing this site I consulted numerous other contributors to our community. I’ve shared the comparison with authors of other frameworks, bloggers who don’t endorse any particular framework over another, and even sent it to one of the jQuery team members. As I receive feedback, I’ll update the site to incorporate the perspectives of others that may be helpful for the target audience of the comparison (i.e. people considering the two frameworks).

I encourage you to leave comments on the site itself and not here on clientcide.

read on: jQuery vs MooTools

The Difference Between Element.set/get and Element.store/retrieve

December 29th, 2008 by Aaron N.

Posted today in the MooTools user group:

Hi!

after a lot of mootools programming and docs studies, I still have a
little question:

when should I use get/set and when store/retrieve? Or, in other words,
what’s the best use for get/set and what’s the best for store/
retrieve?

Element.get/set are used for element properties (img src, element class, input value, etc) as well as custom values that include special properties (like ‘html’ and ‘text’ as well as ’styles’ and ‘events’) and default properties for built-in classes (el.set(‘tween’, options)). Element.set/get almost always accepts and returns strings and objects including the built-in instances of classes (which are also objects) – el.get(‘tween’) returns the built-in instance of Fx.Tween.

Examples:

//setting properties of elements
input.set('value', 'foo');
checkbox.set('checked', true);
myDiv.set('html', '<b>bold!</b>');
myImg.set('src', url);
//set can also take an object
myDiv.set({
  styles: { width: 100, height: 100}
  events: {
    click: function(){ alert('you clicked me!'); }
  }
});

//using custom setters/getters
element.set('tween', {duration: 500});
element.get('tween').cancel();

Storage is for storing arbitrary values for an element. These values may be any object type – boolean, array, object, function, class, etc. You can store any data and retrieve any data and not worry about memory leaks (if you stored these things as properties of the elements you would risk creating circular references, which are the main causes of such leaks.

Examples:

//storing misc. data
myImg.store('mouseOverImg', alternateSrcUrl);
myGalleryDiv.store('galleryImgs', $$('img.slide'));
//storing pointers to instances of classes
var myValidator = new FormValidator(myForm);
myForm.store('myFormValidator', myValidator);

You can define custom setters and getters for ‘default’ instances of classes or for other logic as you like. The benefit here is that when you call el.get(‘tween’) until that moment the element doesn’t have a default instance of Fx.Tween. It’s only when you use the getter or setter that it is created.

Example from Fx.Tween:

Element.Properties.tween = {
	set: function(options){
		//get the instance of tween if there is one already
		var tween = this.retrieve('tween');
		//cancel it's operation if it's running
		if (tween) tween.cancel();
		//store the new options and return the element
		//note that element.set always returns the element
		return this.eliminate('tween').store('tween:options', $extend({link: 'cancel'}, options));
	},
	get: function(options){
		//if options were defined with the get instruction, store them
		if (options || !this.retrieve('tween')){
			//store the options
			if (options || !this.retrieve('tween:options')) this.set('tween', options);
			//create a new instance with those options
			this.store('tween', new Fx.Tween(this, this.retrieve('tween:options')));
		}
		//return the instance
		return this.retrieve('tween');
	}
};

Finally, you can implement methods into the Element prototype to reference these default values (element.tween(‘opacity’, 0) and element.fade(‘out’) both call element.get(‘tween’) to execute their logic).

Again, from Fx.Tween:

Element.implement({
	tween: function(property, from, to){
		//get the instance of tween and start it
		this.get('tween').start(arguments);
		//return the element
		return this;
	}
});

MooTools Class Mutators

December 11th, 2008 by Aaron N.

This question got posted to the MooTools User Group earlier and I thought I’d answer it here because it’s pretty interesting:

Hey everyone,

I just discovered Mutators today when I was digging through the mootools source. I’ve been using mootools for a couple of years now and am pretty familiar with some of it’s internals. Coming from a heavy OOP background I found the whole extending and implementing classes in JS very interesting. So, what I’m really wondering is this:

What is the formal definition of Mutators?

What are the pros and cons of developing them to add features to JS classes?

Thanks,
Brandon

Mutators take properties of classes and process them in specific ways. MooTools only ships with the two: Extends and Implements. It’s important to note that mutators are applied to the class when you invoke new Class, so they can only be used to alter classes themselves, not instances of them. So, for instance, Extends is processed when you do this:

var Widget = new Class({
Extends: Foo,
initialize: function(){ ...}
});

Extends creates a new instance of Foo and mixes it in to Widget. Unlike the initialize method, which is used when you invoke new Widget.

In general, mutators are useful when you want to run functionality when classes are created, but not when they are instantiated. This low level access lets you change the way classes themselves work, but only in this very specific way. The only mutator that I’ve ever actually found a user for was the Class.Binds mutator (which I originally got from Jan), which let you do this:

var Widget = new Class({
binds: ['click'],
initialize: function(el) {
el.addEvent('click', this.click);
},
click: function(){
console.log(this);
}
});

Normally the console statement above would log el because this by default points to the element unless you use Function.bind to make sure the method is bound to your instance of the class.

The Class.Binds mutator let you specify a property (binds) that listed the names of methods that should automatically be bound to the instance of the class.

MooTools 1.2 reworked how classes work a bit (mostly to work around Opera bugs and the like). Consequently mutators like Class.Binds won’t work, because they need to be applied when you invoke the class (new Widget) in order to bind them to that instance. I have a Class.Binds replacement that runs at runtime that almost duplicates this entirely (you have to call a method to bind the classes).

MooTools 1.3 should include a post-instantiation mutator that will let me make Class.Binds work the way it used to (i.e. invoke a method when the class instance is created).

The only other mutators that I’m aware of were authored by Nathan White that were designed to create Singletons and to help with the creation of private methods through closures.

Update: Nathan points out that there’s also an Exposes mutator that Jan put together.

Ask Clientcide: How do you randomize your header?

November 21st, 2008 by Aaron N.

I get a lot of emails from people. Sometimes it’s a charitable soul sending me a bug report (via google code) and, sometimes, an even more charitable soul sending me bug fixes (these are my favorite types of people). Then there’s the Clientcide google group, which is where I prefer questions about my code go so that future readers can see the answers, too.

But today I got this email:

Can you write a blog about how you change the images in your
header.

I like your new design so much.

-shin

Awww shucks. Why thank you shin, I like it, too.

So I added a new contact page specifically for suggesting topics you’d like to see me write about (Post a Question / Suggest a Post Topic). And, for starters, I’ll answer this question from shin.
Read the rest of this entry »