MichaelR: AJAX

Hallo zusammen,

ich bastle gerade an einer minimalen AJAX-Klasse:

  
var AJAXRequest = null;  
  
function AJAX(){  
	this.xmlHTTPObj = null;  
	this.Method = "POST";  
	this.Header = "";  
// ... andere Eigenschaften	  
	this.Create();  
}  
  
AJAX.prototype.Create = function(){  
	// construct the HTTP request object  
	try{  
		this.xmlHTTPObj = new XMLHttpRequest();  
		}  
		catch(e){  
// andere Methoden zur Erzeugung des XMLHttpRequest-Objekts				}  
}  
  
AJAX.prototype.Send = function(strURL, strDataToSend){  
	this.xmlHTTPObj.overrideMimeType("text/xml");  
	this.xmlHTTPObj.onreadystatechange = this.ProcessRequest;  
	this.xmlHTTPObj.open(this.Method, strURL, true);  
}  
  
AJAX.prototype.ProcessRequest = function(){  
//TODO  
	_this = AJAXRequest;  
	  
	switch (_this.xmlHTTPObj.readyState){  
		case 0 : // not initialised  
			break;  
		  
		case 1 : // loading ...  
			break;  
			  
		case 2 : // loaded  
			break;  
			  
		case 3 : // interacting	  
			break;  
			  
		case 4 : // done  
		if (_this.xmlHTTPObj.status == 200){  
				_this.ResponseText = _this.xmlHTTPObj.responseText;  
				_this.ResponseXML = _this.xmlHTTPObj.responseXML;  
				  
					_this.funcHandleResponse();  
					}  
				}  
				else{  
					// error status 404, 500, usw.  
					}  
			break;  
		}  
}  

So, ich erzeuge obige Klasse und setze verschiedene Parameter und dann wird die Anfrage an den Server geschickt. In der Methode ProcessRequest kennt das Objekt allerdings this.xmlHTTPObj nicht mehr und ist der Meinung es sei null. Obwohl in keinem Programmaufruf vorher oder nachher das AJAXRequest Objekt gelöscht wird.

Ich hab das ganze jetzt nur so zum Laufen gebracht, dass ich statt

this.xmlHTTPObj. ...

die obere Variante verwende und das ganze über eine Hilfsvariable mache.

Weiß jemand, warum in einer Klassenfunktion plötzlich das Objekt this.xmlHTTPObj nicht mehr existent ist?

Grüße
Michael

  1. Hallo,

    In der Methode ProcessRequest kennt das Objekt allerdings this.xmlHTTPObj nicht mehr und ist der Meinung es sei null.

    Ist es doch auch:

    var AJAXRequest = null;  // <-- Hier wird AJAXRequest zu null und dann nie mehr gebraucht

    [...]

    AJAX.prototype.ProcessRequest = function(){

    »»

    _this = AJAXRequest; // <-- Hier ist es noch immer null, also auch _this

    switch (_this.xmlHTTPObj.readyState){ // <-- Und das müsste natürlich den Fehler werfen

    [...]

      
    
    > Ich hab das ganze jetzt nur so zum Laufen gebracht, dass ich statt  
    >   
    > this.xmlHTTPObj. ...  
    >   
    > die obere Variante verwende und das ganze über eine Hilfsvariable mache.  
      
    Welche obere Variante?  
    Hast du überhaupt den richtigen Code gepostet?  
      
    Das Ganze scheint mir von der Notation her etwas umständlich.  
    Es gibt doch massenhaft gute AJAX-Scripts im Web (nehme ich an, bin da aber kein Spezialist).  
    Warum willst du das Rad zum xten Mal neu erfinden?  
      
    Gruß, Don P  
    
    
  2. Grüße,
    ich glaube, ich irre mich, aber muss man die global deklarierten variablen, um sie innerhalben von fuincitons namespace nutzen zu können, mit global Varname; nehmen?
    MFG
    bleicher

    --
    __________________________-

    FirefoxMyth
  3. Hallo,
    Entscheidend für die Beantwortung Deiner Frage ist diese Zeile:

      
    this.xmlHTTPObj.onreadystatechange = this.ProcessRequest;  
    
    

    Du weist setzt damit (abstrakt gesprochen) die Eigenschaft "onreadystatechange" von "this.xmlHTTPObj" auf ein anderes Funktionsobjekt.
    Somit ändert sich der Scope: "this" bezieht sich nun nicht mehr auf die Instanz deiner AJAX-Klasse sondern auf das xmlHTTPObj dieser Instanz, und diese kennt natürlich keine Eigenschaft "xmlHTTPObj" mehr.

    Du kannst das Problem so lösen wie Du es tust (über eine globale Variable) oder z.b. über Closures
    lösen.

    Etwas wie

      
    var scope = this;  
    this.xmlHTTPObj.onreadystatechange = function() {scope.ProcessRequest};  
    
    

    müsste z.b. gehen (ohne Gewähr).

    Oder Du klebst den Scope an das xnmlHHTObj dran:

      
    this.xmlHTTPObj.scope = this;  
    this.xmlHTTPObj.onreadystatechange = this.ProcessRequest;  
    
    

    Dann müsstest Du in deiner "ProcessRequest"-Methode überall dort, wo jetzt "this" steht, "this.scope" schreiben.

    Hope that helps.

    Viele Grüße,
    Jörg

    1. Sorry,

        
      var scope = this;  
      this.xmlHTTPObj.onreadystatechange = function() {scope.ProcessRequest();};  
      
      

      muss das eigentlich heissen (die Klammern hinter ProcessRequest sind IMO wichtig)