While working on porting "Dojo.Storage" to YUI, I took an in-depth look at the Dojo.Event.Connect method. This is the backbone to many Dojo applications, allowing developers to subscribe to browser events, Dojo events, and to attach functions to be fired after the execution of other functions. And it is this last feature that inspired todays article. Sometimes a developers needs Function B to fire after Function A. Most of the time the developer needs to create a closure to manage the link and then call the closure in place of Function A. However, a better approach is to replace Function A with the closure function, so that no code needs to be changed to call the special closure.
Example 1: mesnider_bind_function
var mesnider_bind_function = function(obj1, func1, obj2, func2, execNum) { if (! obj1) {obj1 = YUI();} if (! obj2) {obj2 = YUI();} if (! (obj1[func1] || obj2[func2])) {return;} // one of the functions doesnt exist, no reason to continue var TEMP_FUNC_NAME = func1 +$oldFunc; var execn = 0; obj1[TEMP_FUNC_NAME] = obj1[func1]; obj1[func1] = function() { obj1[TEMP_FUNC_NAME].apply(this, arguments); obj2[func2].apply(this, arguments); execn += 1; if (execNum && execn >= execNum) { obj1[func1] = obj1[TEMP_FUNC_NAME]; delete obj1[TEMP_FUNC_NAME]; } }; };
The mesnider_bind_function function requires 4 parameters, and 1 optional parameter: the first parameter is the object that the second parameter (the function name as a string) is attached to (the YUI object is used if this object is not provided), parameter three and four are the same structure as one and two, but is the second object and function, and the optional fifth parameter is the limit of times
func2 should be executed when
func1 is called. The second parameter
func1 is the function to be called by code, while the fourth parameter
func2 will be the function executed whenever
func1 is called.
To bind func2 to
func1,
func1 must first be moved to a temporary location (func1 +
$oldFunc) on
obj1 so that it can be called and restored (if necessary). Then
func1 is replaced with a new function that will call both
func1 and
func2, passing any arguments provided to the new
func1 into both
func2 and the old
func1, and iterate the execution counter (
execn). If a maximum execution number (
execNum) was passed to
mesnider_bind_function function then it will be compared against the execution counter (
execn). When the execution counter is equal to or greater than the maximum execution number, then
func1&rsquot; is restored to its previous value and the function binding is removed.
This method simplifies associating the execution of Function B to Function A, opening many possibilities for extending the capabilities of functions, without overriding them. Here is a simple test page to show 3 different ways to use this method.