Here's one I've been struggling with for a bit now. I need to make a setTimeout() call to a method or function inside of a class and pass a parameter. Say I'm in a method and inside of that method I need to fire a request to do delayed execution of another method in the same class.
Outside of classes you can do this:
if (Timeout && Timeout > 0)
window.setTimeout("HideToolTip('" + ControlId + "')",Timeout);
This works fine with plain global functions. But now imagine you have a method in a class:
this.ShowToolTip = function (Message,Timeout,Position)
{
…
if (Timeout && Timeout > 0)
window.setTimeout("this.HideToolTip('" + ControlId + "')",Timeout);
}
this.HideToolTip = function(ControlId)
{
… do something with ControlId
}
Now how do you set up the call for window.setTimeout()? Hint: The above doesn't work <s>. The reason is that window.setTimeout doesn't call from within the context of the class so 'this' is not in scope – and the call fails. Same applies if you don't make HideToolTip a class method but plain function inside of the class – it still won't be visible to the window object and setTimeout.
Calling the method is really not that big of a problem. Instead of a string you can pass in an event handler object reference, so you can do this:
if (Timeout && Timeout > 0)
window.setTimeout(this.HideToolTip,Timeout);
That works in firing the method or function, but there's unfortunately no way to pass a parameter. Well, officially there may be.
Incidentally I was browsing through my JavaScript Bible that mentioned this working:
window.setTimeout(this.HideToolTip,Timeout,ControlId);
and it actually works in FireFox, but unfortunately not in InternetExplorer. Looking online though I don't see this syntax referenced in any of the browser references. So that's out… Too bad cause that would have been easy.
What about calling the class method and letting class properties deal with 'passing' of values? So instead of trying to pass a ControlId why not set a property on the object or use some property, something like this (using ATLAS for that matter):
this._hideToolTip = function (ControlId)
{
var ControlId = $(this.element.id);
var Ctl = $(ControlId + "_ToolTip");
if (Ctl == null)
return;
Ctl.style.display="none";
Ctl = $(ControlId + "_ToolTipShadow").style.display="none";
}
Seem logical OO – but nope that doesn't work. When the setTimeout call is made this, doesn't refer to your object, but to the window object. Grrr… so much for object orientation in JavaScript.
So what's the answer here? Actually I've been looking at how ATLAS does this, but I can't for the life of me get ATLAS events using eventArguments to fire for me either. The events get hooked up but they just never actually trigger the handlers.
So anybody have any ideas on to make call another method in a class with the proper context?
Other Posts you might also like