Atlas 6: When 'this' is not really 'this'
Atlas callbacks are not executed on the same context where they
are called. For ex, if you are making a Page method call from a
javascript class like this:
function
SampleClass() {
this
.id
=
1
;
this
.call
=
function
() { PageMethods.DoSomething(
"
Hi
"
,
function
(result) { debug.dump(
this
.id ); } ); } }
What happens when you call the "call" method? Do you get "1" on
the debug console? No, you get "null" on the debug console because
"this" is no longer the instance of the class. This is a common
mistake everyone makes. As this is not yet documented in Atlas
documentations, I have seen many developers spend time finding out
what's wrong.
Here's the reason. We know whenever Javascript events are raised
"this" refers to the html element which produced the event. So, if
you do this:
function
SampleClass() {
this
.id
=
1
;
this
.call
=
function
() { PageMethods.DoSomething(
"
Hi
"
,
function
(result) { debug.dump(
this
.id ); } ); } }
<input type="button" id="ButtonID" onclick="o.onclick"
/>
If you click the button, you see "ButtonID" instead of "1". The
reason is that, the button is making the call. So, the call is made
within button object's context and thus "this" maps to the button
object.
Similarly, when Xml Http raises the event onreadystatechanged
which Atlas traps and fires the callback, the code execution is
still on the Xml Http's context. It's Xml Http object which raises
the event. As a result, "this" refer to the Xml Http object, not to
your own class where the callback is declared.
In order to make the callback fire on the context of the
instance of the class so that "this" refers to the instance of the
class, you need to make the following change:
function
SampleClass() {
this
.id
=
1
;
this
.call
=
function
() { PageMethods.DoSomething(
"
Hi
"
, Function.createDelegate(
this
,
function
(result) { debug.dump(
this
.id ); } ) ); } }
Here, the Function.createDelegate is used to create a delegate
which calls the given function under the "this" context.
Function.createDelegate is defined in AtlasRuntime:
Function.createDelegate
=
function
(instance, method) {
return
function
() {
return
method.apply(instance, arguments); }
}