Dave Crane
2007-Apr-12 09:36 UTC
Re: Using Ajax.Request, How can I access to parent context inside onSuccess callback ?
Hi,
Use a closure - if you reference the variable a inside the anonymous function
assigned to the onSuccess callback, the interpreter will preserve a reference
to it. So:
function test() {
var a = ''test'';
new Ajax.Request(''/myurl'',
{ method:''get'',
onSuccess: function(transport) {
alert("a = "+a);
}
}
);
}
should work... Note that I just mention ''a'' inside the
onSuccess fn, no
special syntax is needed.
The same technique works for UI callbacks too - great once you start
programmatically assigning UI event handlers inside objects, rather than the
old onclick attributes and pals.
Closures are a very powerful feature of JavaScript, enabling a much more
fluid style of coding than the pure OO approach. Once you start getting your
head around them, they can''t be beat.
HTH
Dave
On Thursday 12 April 2007 11:15, scramatte wrote:> When I made an Ajax Request, how can I access to parent context
> inside onSuccess callback.
> I mean that in the example below I would like to get value of var
> "a"
----------------------
Author
Ajax in Action http://manning.com/crane
Ajax in Practice http://manning.com/crane2
Prototype & Scriptaculous in Action http://manning.com/crane3
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Spinoffs" group.
To post to this group, send email to
rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-spinoffs?hl=en
-~----------~----~----~----~------~----~------~--~---
Yanick
2007-Apr-12 14:02 UTC
Re: Using Ajax.Request, How can I access to parent context inside onSuccess callback ?
Like Dave said, closures may be hard to understand at first, but it
is, in fact, one of the most important thing to understand when
writing JS scripts. Consider this :
----------------------------------------------------
var AjaxEngine = Class.create();
ajaxEngine.prototype = {
initialize: function(id) {
this.id = id;
},
request: function(url, callback) {
var options = {
method: ''get'',
onSuccess: function() { callback(this.id); }
};
new Ajax.Request( url, options );
}
};
var successFn = function(id) {
alert( id );
};
new AjaxEngine("test").request( "page.php", successFn );
----------------------------------------------------
(Let suppose the file page.php exists on the server, and the onSuccess
method of the ajax request is executed)
What do you think will be the output printed in the alert box ?
If you say "test", guess again. Why ? Who called the onSuccess
function ? The object AjaxEngine never calls anything except the
method Request of the new Ajax object (new Ajax.Request...). In fact,
it is that Ajax object who called it, so the keyword ''this''
refers to
that object. For this reason, ''this.id'' is
''undefined''.
Therefore, in this particular script, it is impossible to know what
AjaxEngine object was successful. To return the information we need,
we must "bind" the function so it will always be called in a
particular context. Fortunatly, Prototype offers that function :
bind(), which is a member of the Function prototype. Consider
replacing the line :
onSuccess: function() { callback(this.id); }
by
onSuccess: function() { callback(this.id); }.bind(this)
Since the onSuccess assignement is executed in context of the
AjaxEngine (we called new AjaxEngine().request....) then the binding
is done with the AjaxEngine object (this). For this reason, the
''this''
inside the function, however the function may be called, is always the
same this as the one ''this'' used to bind the function with.
With this
modification, the alert will display "test".
The keyword ''this'' always refers to the exact object used to
call the
function. As this :
var Example = function(id) {
this.id = id;
};
Example.prototype = {
func: function() {
alert(this.id);
}
}
var obj1 = new Example("test1");
var obj2 = new Example("test2");
obj1.func(); // will output "test1"
obj2.func(); // will output "test2"
obj1.func.bind(obj2).call(); // will output "test2" because of
binding
I suggest you familialize yourself with closures and binding, so you
will minimize the chance your code will be messy, hard to maintain,
and cause memory leaks.
-yanick
On 12 avr, 05:36, Dave Crane
<d...-qrf20pp95eSLQvtTh0HkdajZmZ73YKuj@public.gmane.org>
wrote:> Hi,
>
> Use a closure - if you reference the variable a inside the anonymous
function
> assigned to the onSuccess callback, the interpreter will preserve a
reference
> to it.
[snip]
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Spinoffs" group.
To post to this group, send email to
rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-spinoffs?hl=en
-~----------~----~----~----~------~----~------~--~---