PDA

View Full Version : form submit callback scope



jthorn
10 Aug 2007, 12:08 PM
Hi All,
I am still trying to get a grasp of scope, closures, and some of the OO idioms. I have read the references, tutorials, etc. In particular, I am having trouble trying to access my objects members in the result of a form success callback.

First of all, for my own sanity, can someone explain the difference between the two function definitions below (init and onSuccess) and when either should be used. I have seen both used frequently.

Second, I think I understand why my onSuccess method is not getting called. The submit callback function does not have scope within my sample object. Can someone tell me the preferred way to handle this situation where the callback needs to access the existing object data (for example sample.data1).

Thanks so much for your help and patience!

Jeff



var sample = function() {

var data1,

return {

init: function() {

var f = new Ext.form.Form({
labelAlign: 'right'
});

f.fieldset(....)

var submit = f.addButton({
text: 'Upload',
handler: function() {
f.submit({
url: 'doSubmit',
success: onSuccess,
}
}
});
}
}

var onSuccess = function(form, action) {
// need the obects data1 variable
// this never gets called because the scope is wrong?
}

}();

Ext.onReady(sample.init, sample, true);

wolverine4277
10 Aug 2007, 12:36 PM
Maybe the extra coma is the problem...


...
f.submit({
url: 'doSubmit',
success: onSuccess, <==
}
...

about the scope you can add


scope: desiredScope

in the config object of the call to submit for a form...


...
f.submit({
url: 'doSubmit',
scope: desiredScope,
success: onSuccess
}
...

Wolfgang
10 Aug 2007, 12:51 PM
Hello,

good questions ... and not so easy to explain in a few sentences. :)

assign an anonyoums function to var sample.
(anonyoums function means: a function without a name)


var sample = function() {
var a = 'a';
alert(a)
return a;
};


execute the function. x has the value of 'a'. alert popups


var x = sample();


execute an anonyoums function (do the alert) and assign the result to var sample.
so here the function is not assigned but executed. Note the '()' at the end!


var sample = function() {
var a = 'a';
alert(a)
return a;
}();



Now this is similar to your init where you return an object that itself contains properties that can be functions.
Note: {init:'...', getValueOfA: '...'} is an object notation. So the function returns an object.


var sample = function() {
var a = 'a';
alert(a)
return {
init: function() {alert('init called'); },
getValueOfA: function() {return a;}
};
}();

Now sample contains two properties that are functions:
sample.init()
sample.getValueOfA()

Ok, now why doing this?
The last example uses a technique called a closure to have private vars. In this case it is var a.
Although the function was executed, var a is still kept in memory, because the returned object (which has 2 properties 'init' and 'getValueOfA') keeps a reference to it.
On the other hand, var a cannot be modified anylonger except there would be another function returned that would allow to change var a.

Here an example of a factory (that produces functions):


function myfactory(myinit) {
var a = myinit || '';
return {
init: function(my) {a = my; alert('init called'); },
getValueOfA: function() {return a;},
setValueOfA: function(my) { a = my;}
};
};



Now we can do:


var sample = myfactory(5); // passed value initially
var newSample = myfactory();

newSample.init(10);
sample.getValueOfA(); // return 5
newSample.getValueOfA(); // return 10


scope
When a function is exectued, scope usally defines what this is pointing to.
Example:
If scope is set to "newSample", "this.getValueOfA" would return 10.
If scope is set to "sample", "this.getValueOfA" would return 5.

This becomes important when callbacks are triggered, usally from events (so called event handler).
If the eventhandler does its processing it is often necessary to pass the information on which object it should operate, because the event handler might be triggered by different objects.
When using something like:
this.myattribute
or this.myfunction
within the eventhandler, what would this point to?
So by defining scope, the eventhandler knows which object to work with.

In general, scope is related to the order of how to resolve properties of objects.
Again an example, using the object notation.


var myObject = {
a: 'a',
z: 'z',
subObject: {a: 'z', z: 'a'}
}


Object looks like:


myObject.a // a
myObject.z // z
myObject.subObject.a // z
myObject.subObject.z // a

So in the scope of "myObject", this.a == 'a'.
However in the scope of "myObject.subObject", this.a=='z'.

Other aspects of scope cover inheritance / prototypes

This might get you a starting point.

Wolfgang

jthorn
13 Aug 2007, 5:42 AM
Wolfgang,
Thank you for your detailed response. It is definitely helpful. I come from a strict OO background, but like most JS newbs, I have always used java script procedurally. If I am going to make the move to OO JS, I would prefer it to be all or nothing.

To wrap up my original problem, then, it sounds like I need to pass the scope along in my submit handler, as you and wolverine suggested. Would the following code snipped be the correct approach then if I want my submit callback to access my object data?



var sample = function() {

var data1,

return {

init: function() {

var f = new Ext.form.Form({
labelAlign: 'right'
});

f.fieldset(....)

var submit = f.addButton({
text: 'Upload',
handler: function() {
f.submit({
url: 'doSubmit',
success: onSuccess,
scope: sample // or should it be this?
}
}
});
}

onSuccess: function(form, action) {
// will this get called with the value of data1 still available?
}
}
}();


Thanks again for your help.

Jeff

ps - Wolverine...the extra comma was a copy and paste error in the sample code only. It was not the problem I was having. Thanks though!

Wolfgang
13 Aug 2007, 9:53 AM
Yes, if you set scope to 'sample', your success handler will have access to data1.

If you do not set scope, 'this' will point to the global window object or to the object you are currently working with when the callback is called thus having no access to data1.
Regards

Wolfgang