public
Last active

Singleton wrapper around $.Callbacks to emulate Backbone events

  • Download Gist
Events.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
Events = (function( $ ) {
 
// Store each registered $.Callbacks object by namespace
var cache = {},
slice = [].slice;
 
return {
// Bind callback to event
bind : function( ev, callback, options ) {
// Make $.Callbacks default to having stopOnFalse
options = options || 'stopOnFalse';
// If this callback list does not exist, create it
if ( !cache[ ev ] ) {
cache[ ev ] = {
cb : $.Callbacks( options ),
funcs : []
}
}
// Add callback to $.Callbacks
cache[ ev ].cb.add( callback );
cache[ ev ].funcs.push( callback );
}, // bind
updateOptions : function( ev, options ) {
var inc, len, func;
// Ignore update if it didn't exist
if ( !cache[ ev ] ) {
return;
}
// Remove all callbacks from $.Callbacks
cache[ev].cb.empty();
// Create a new $.Callbacks list with the new options
cache[ ev ].cb = $.Callbacks( options );
// Get size of callback functions already added
len = cache[ ev ].funcs.length;
// Loop through array of callback functions to insert into fresh $.Callbacks
for ( inc = 0; inc < len; ++inc ) {
func = cache[ ev ].funcs[ inc ];
cache[ ev ].cb.add( func );
} // for inc
}, // updateOptions
 
unbind : function( ev, callback ) {
// Ignore unbind if it didn't exist
if ( !cache[ ev ] ) {
return;
}
// Remove from list
cache[ ev ].cb.remove( callback );
// Remove from cache of funcs for option change
cache[ ev ].funcs = $.grep( cache[ ev ].funcs, function(value) {
return value !== callback;
});
}, // unbind
 
trigger : function( ev ) {
// Ignore trigger if it doesn't exist
if ( !cache[ ev ] ) {
return;
}
// Get dynamic number of arguments, knowing first argument is always event
var args = slice.call( arguments ),
pass = args.splice(1);
// Call $.Callbacks fire method with right arguments
cache[ ev ].cb.fireWith( null, pass );
} // trigger
} // return
 
})( jQuery ); // Events
test.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
var a = function() {
console.log('a');
return false;
};
 
var b= function() {
console.log('b');
};
 
Events.bind( 'foo', a );
Events.bind( 'foo', b );
 
// Logs a
Events.trigger( 'foo' );
 
Events.updateOptions( 'foo', '' );
 
// Logs a then b
Events.trigger( 'foo' );
 
Events.updateOptions( 'foo', 'stopOnFalse' );
 
// Logs a
Events.trigger( 'foo' );
 
Events.unbind( 'foo', a );
 
// Logs b
Events.trigger( 'foo' );

Line #30: you missed the [ev]
Line #46: you could use fireWith( null, pass );

Thanks @jaubourg for that catch on #30. I didn't need unbind where I first wrote this so didn't see that bug yet. Also you're right about fireWith since fire just calls fireWith anyway. Didn't look at the internals until just now.

Here is my take on it. I have removed the options in bind given how situational it is (will work the first time, not the second, etc).

https://gist.github.com/1387553

That's a great point about the options. I'm gonna see if I can re-configure
it so options can be changed after the fact.

Changing it from a singleton to a revealing module is something I should
probably do, to avoid cache from being exposed.

Thanks for all the input. I'll give a shout on the post and on twitter once
I finish making the changes.

On Tue, Nov 22, 2011 at 7:57 PM, Julian Aubourg <
reply@reply.github.com

wrote:

Here is my take on it. I have removed the options in bind given how
situational it is (will work the first time, not the second, etc).

https://gist.github.com/1387553


Reply to this email directly or view it on GitHub:
https://gist.github.com/1384615

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.