JavaScript MVC: Inheritance

If you’ve ever done a lot of JS development you might find the following situation familiar: you’re loath to open up the bowels of the sweet webapp you wrote because you know inside you will find hundreds of lines of jQuery selectors stacked on top of each other. Try as you might, they just won’t be tamed simply by separating out into distinct functions. Soon you’re lost in your own code, trapped in a Borgesian labyrinth of your own making.

That was one of the first challenges we ran into when I started working at Behance: the decentralized, deframework-ized nature of the client side code. Like many other shops, JavaScript was viewed with equal parts suspicion and distaste. But as our code grew, it became increasingly impossible to continue working the same way as thousands of lines of JS collided tectonically into each other as Everests grew out of merge conflicts.
Read more →

Emulate Backbone Events with jQuery 1.7 $.Callbacks

I just started the fun upgrade process from jQuery 1.6 to 1.7 across our apps. One of the things that’s been missing from jQuery for a long time are non-DOM based events. In places where I needed them, I took the bind/unbind/trigger methods from Backbone.js.

Now $.Callbacks enters the room with a standing ovation. It lets developers control lists of callbacks that will all fire at once. For example you can create

// Register list
var cartUpdated= $.callbacks();

// Add callback1 to list
cartUpdated.add( callback1 );

// Add callback2 to list
cartUpdated.add( callback2 );

// Fire so both callbacks run
cartUpdated.fire( "quantity", "price" );

What I find is that this syntax is very powerful in most basic cases with one file. It becomes too coupled once more than one file is introduced though. To alleviate the coupling problem, I have created a small singleton, Events. The full singleton code is a gist here. The idea is that Events wraps fire/add/remove with trigger/bind/unbind to get the power of traditional DOM-related events. For instance I can trigger any event on an element at any point, without worrying if anything was bound or created beforehand. $.Callbacks doesn’t natively allow that. As you saw above, you need a reference to “cartUpdated.” This singleton allows for that blind firing that proves useful in many cases.

Read more →