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.
// Inside View 1, bind callback1
$('#cart_total').bind( 'cartUpdated', callback1 );
// Inside View 2, bind callback2
$('#cart_total').bind( 'cartUpdated', callback2 );
// Inside controller, trigger the event.
Events.trigger( 'cartUpdated', 5, 10.00 );
The advantage of the above code allows us to blindly fire events without any other files having to worry about it being registered first. To be clearer, I don’t need to worry about saving off “cartUpdated” somewhere from the first example in comparison to the second.
Anyway I made this in a few minutes after checking out callbacks so I’m very open to thoughts and feedback so let me know and I’ll get back.
UPDATE 11/23/2011
I have to thank @jaubourg for the back and forth on the gist.
He noted how you can’t update “options” after the fact so he took it out.
I went the other way and made it so you can update “options” but I took “context” out, since that can be done externally anyway. You’d just need to use $.proxy and save that off for your bind/unbind. ( func != $.proxy( func ) ).
The gist now has the full code plus my little test using the new function, updateOptions. It’s also now using the revealing module pattern, rather than being a plain singleton, thanks to Julian’s suggestion. Enjoy.
Thanks for this sharing this code to us!
Outstanding post, I believe people should learn a lot from this blog its really user pleasant. “A happy childhood has spoiled many a promising life.” by Robertson Davies.