PDA

View Full Version : Get reference of object from inside Ajax call



mad_ady
10 Mar 2010, 12:47 PM
Hello everyone,
Sorry for this rather long question (which may not even be specific to Ext), but I need your help to solve this design issue.

Here's the problem: I've followed some tutorials on the net and I have built my interface, but now I am refining my code and basically I am creating a class for every window type I use. This class contains the methods and attributes (datastore/column model/grid) that are used by a particular window.

Here's how it looks like (in brief):



//Class definition
function PizzaBox() {
// initialize attributes
this.dataStore = new Ext.data.Store({ bla bla bla });
this.dataStoreURL = "something.php";

//initialize methods
this.initAndShow = function () { bla bla };
this.save = function () {
//do something and make an Ajax request
Ext.Ajax.request({
waitMsg: 'Please wait - saving...',
url: this.dataStoreURL,
params: {
task: "UPDATE"
},
success: function(response){
//I want to commit the object's dataStore...
// this doesn't work, since "this" isn't the original PizzaBox object I need
this.dataStore.commitChanges();
// this could work, but I would be bound to a single object (and it's hardcoded...)
pizzabox.dataStore.commitChanges();

}
});
};
};

//create a PizzaBox object
var pizzabox=""; //global variable to access the object
Ext.onReady(function(){
pizzabox = new PizzaBox();
pizzabox.initAndShow();
});
The problem with the code above is that I need to access some of the object's attributes in the "success" function from an ajax call. The methods I've tried (using "this") don't work because the variable scope isn't the same as the method that calls the Ajax (most likely because the whole thing is asynchronous). this.dataStoreURL works just fine because this is a reference to the object as seen in the save method. However, it doesn't work on the success method...

I want to know what is the best way to access the datastore (in my case) from a success function from an Ajax call made from a method inside the class? Is there any way I can pass a reference to my object ("this") to the "success" function? The tutorials solved this by using global variables, but I really don't want to clutter my code with those... (it will be harder to copy paste it in the future in new projects) :)

Hope I presented my problem in an understandable way, and sorry if it's been asked before - I didn't manage to find the correct solution...

A point/kick in the right direction is appreciated

steffenk
10 Mar 2010, 12:54 PM
success: function(response) {
...
}.createDelegate(this);

mad_ady
10 Mar 2010, 10:20 PM
Thank you steffenk,
I haven't seen that before so I'll give it a try.
Quick question (haven't tried it yet) - will this allow me to refernce the parent object as "this" in the "success" function?

Thanks again!

mad_ady
11 Mar 2010, 5:12 AM
Thanks steffen! It worked like a charm :)

Animal
11 Mar 2010, 5:18 AM
How many PizzaBoxes may be created during your page's existence?

mad_ady
11 Mar 2010, 6:09 AM
Animal: About 3 or 4.

Animal
11 Mar 2010, 6:13 AM
Well it won't be too bad then You're just creating new member functions each time the constructor is called instead of putting member functions into the shared prototype.

mad_ady
11 Mar 2010, 7:58 AM
What are you suggesting (for a larger project)? Should I create some sort of template class with the functions and derive/inherit other classes which have slightly different attributes from that template? Would that save me memory at run-time compared to what I'm doing now?

How much memory do functions consume anyway? I thought they were interpreted when they were needed.

Please correct me if I'm wrong

Animal
11 Mar 2010, 8:17 AM
Well they are created when you create them. I'm just suggesting create class in the way classes are usually created.

By putting shared properties into a prototype.

mad_ady
11 Mar 2010, 10:24 PM
Hmm, seems that I have to do additional reading on classes in javascript. I thought that by doing


function PizzaBox() {
this.function1 = function() { ... };
this.attribute1 = "bla"
}

... I was actually defining the prototype of the PizzaBox class and each object would be created by calling new PizzaBox();

mad_ady
11 Mar 2010, 10:31 PM
Oh, I think I get it now...
The fact that I define a new dataStore in each instance of PizzaBox will consume more memory (if the dataStores are identical). Is this what you mean by putting shared properties in a prototype? Are these shared properties similar in behavior to "static" class variables in Java (meaning the same "object/variable" is referenced in each object)?

Animal
12 Mar 2010, 12:05 AM
Well, if there's only one set of records shared among all PizzaBoxes, only create one Store, put it into the PizzaBox prototype so that it can be shared.

mad_ady
12 Mar 2010, 1:13 AM
Thank you for your reply. I will keep that in mind in larger projects :)