Forum Moderators: open
if(ajax.request.readyState==4 ¦¦ ajax.request.readyState=='complete'){
IN such a line "ajax" stands for a variable somewhere initialized with such name.
Of course, we can create Ajax classes, and encapsulate all the methods in one wrapper.
Yet, these classes are invariably singletons: only ONE instance can be initialized namely it cannot COEXIST with other instances because it is still required that in the response handlers the name of the instance is hard coded: "ajax", in the example above.
I know of one way to avoid that but it works only in Firefox.
this.echo=function(){
if(ajax.request.readyState==4 ¦¦ ajax.request.readyState=='complete'){
if(ajax.request.status==200){ blah blah
Obviously, this.echo is the method member of a class.
If you produce a snippet like:
this.assignCallingVariable=function(assignTo){
assignTo.variable=this;
}
and soon after this.echo has been defined you do:
this.assignCallingVariable(this.echo);
from that moment on you could redraw the echo method as follows:
this.echo=function(){
if(this.variable.request.readyState==4 ¦¦ this.variable.request.readyState=='complete'){
if(this.variable.request.status==200){
as you may notice, the generic placeholder this.variable has overtaken the hardcoded class instance name "ajax".
This works brilliantly with Firefox: it achieves the response going on recognizing the this.variable as a reference to the initialized instance.
However, this does not work with Internet Explorer.
I am not here moving on the plane "how bad IE is" - I am after practical results, not ideological opinions. Just to be clear.
Now, how could we persuade IE to do that?
I am VERY puzzled because IE keeps calling this.echo if the class instance name is hardcoded, so there MUST be somewhere in the engine a POINTER to it, a VALID pointer.
Yet, I cannot spot a ROUTE to take hold of it.
From within this.echo, any reference to 'this' in IE references the window. Of course, I thought to scan the window properties, say
if(!this. variable){loop window, if 'X'==windowProp then this.variable='X'}
The issue is now twofold: apparently, the window scoped variables in IE do NOT belong to the window object, or at any rate can NOT be found scanning it (!), second issue: what should 'X' be? it is obviously a reference to the ajax instance that is repeatedly calling the this.echo method, and yet I have no clue at this stage how to reference it, that is what to put in place of 'X'.
Anyone has tried to deal with this generalization issue before, successfully?
Thank you
Alberto
[edited by: jatar_k at 2:28 pm (utc) on Aug. 27, 2006]
[edit reason]
[1][edit reason] no sigs thanks [/edit] [/edit][/1]
The methods that are tailored to handle the echo (this.request.onreadystatechange) trigger the echo handler. Yet, once the echo handler runs, it needs to have within it hardcoded the name assigned to the instance of the class, or won't be able to work.
Say this pseudocode;
class AJAX{
this.request=function(){} /*request CAN be stored in the class*/
this.get=function(){}
this.echoHandler=function(){} /*here we'll have an issue*/
}
var ajax=new AJAX();
Now, you must write down in the echo method the name 'ajax', or it would not work, simply (unless I am missing something, but all codes I saw seem to "suffer" of this very same lack of generalization):
this.echoHandler=function(){
if(ajax.request.readyState==4 ¦¦ ajax.request.readyState=='complete'){etc...}
}
The problem is: how to avoid writing down:
ajax.request.readyState /*see? I had to write down the NAME of the instance: 'ajax'*/
and be able to generalize with something like:
INSTANCE_NAME_WHATEVER_IT_WAS.request.readyState
As said, there is a way to do this with Firefox, but not with Explorer - for more on this see my previous post, or ask further questions if that wasn't clear enough.
Thank you
Define the object:
function myobject(init1, init2, init3) {
this.attribute1 = init1;
this.attribute2 = init2;
this.attribute3 = init3;
}
myclass.prototype.set1 = function(value) {
this.attribute1 = value;
}
myclass.prototype.show1 = function() {
alert(this.attribute1);
}
Use the object:
var myinstance = new myobject('one', 'two', 'three');
myinstance.show1(); // alert dialog shows 'one'
myinstance.set1('first')
myinstance.show1(); // alert dialog shows 'first'
As you see, there's no need at all to hardcode any names that are external to your object. Knowing this, maybe your original problem will just disappear... ;)
What I am after is a level of abstraction that seems not only more elegant, but more productive.
If I can track (both on IE and FF) from the echo handler that produces the response, the class instance that triggered it, we can produce something interesting.
class AJAX{
//bla bla
this.echoHandler(){}
}
var ajax1=new AJAX();
ajax1.INSIDEechoHadler=function(response){alert(response)}
which would mean that this.echoHandler is sort of:
this.echoHandder{
if(PLACEHOLDER.request.readyState==4 ¦¦ PLACEHOLDER.request.readyState=='complete'){
if(PLACEHOLDER.request.status==200){
PLACEHOLDER.insideechoHandler(PLACEHOLDER.request.responseText)
}
}
that is, we can avoid writing down in the echo handlers the same code again, over and over, for the readyState status checks.
This is the level of abstraction I am after, but being echoHandler an ASYNCHRONOUS method, once it is triggered one time, any reference within it made to the instance by the 'this' keyword, gets lost.
You need to prepare a special function that remembers "this". The process is called currying, and requires a second "factory function", which dynamically creates a wrapper function around your actual handler (it sounds more complicated than it actually is... ;))
function myobject() {
}
myobject.prototype.handler = function(arg) {
alert('this is ' + this + ' handling ' + arg);
}
myobject.prototype.create_handler = function(my_this) {
return function(arg) { my_this.handler(arg) }
}
var myinstance = new myobject('one', 'two', 'three');
var handler = myinstance.create_handler(myinstance);
// use handler as callback function
The function returned by create_handler will remember "this". The procedure is not very intutitive, but you can juse the above as a pattern that always works when you need a callback that remembers which object instance it belongs to.
It is amazing that after 10 years of javascript, one has still to learn about it - my only excuse, being not a mathematician, I was not really supposed to know that javascript had an implementation for... Lambda Calculus!