# Ajax-Klasse



## versuch13 (6. März 2007)

Hi, ich habe hier ein JavaScript / Ajax Buch vor mir, und versuche mir eine kleine Klasse für Ajax Anwendungen zu schreiben. Allerdings will es natürlich nicht so wie ich das will.

Ich poste einfach mal den Quelltext, ich denke daraus wird sehr gut deutlich was ich erreichen möchte.


```
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Unbenanntes Dokument</title>
<script type="text/javascript">
<!--

    function AjaxRequest() {    
        this.req = (window.XMLHttpRequest)    
                   ?    
                   new XMLHttpRequest()    
                   :    
                   ((window.ActiveXObject)    
                   ?    
                   new ActiveXObject("Microsoft.XMLHTTP")    
                   :    
                   false    
                   );     
    }
    
    AjaxRequest.prototype.updateElement = function(method,url,element) {
        this.req.open(method,url,true);    
        this.req.onreadystatechange = function() {
            if(this.req.readyState==4) {
                if (this.req.status == 200) {
                    var e = document.getElementById(element);
                    e.innerHTML = this.req.responseText;
                }
            }
        }    
        this.req.send(null);    
    }
    
    AjaxRequest.prototype.sendData = function(method,url) {
        /* ... */
    }

    window.onload = function() {
        var ajax = new AjaxRequest();  
        ajax.updateElement('GET','hallo.txt','hallo');
        alert(ajax.req);
    }
    
//-->
</script>
</head>
<body>
    <div id="hallo"></div>
</body>
</html>
```

Wie man in der onload Funktion sieht, möchte ich hier jetzt zum Beispiel ein Ajax Objekt erstellen und dann eine Methode aufrufen. So wie ich das hier in dem Buch verstehe, sollte ich jetzt eigentlich durch die prototype Erweiterung die Möglichkeit haben auf "this.req" zuzugreifen, funktioniert aber nicht. Was läuft denn hier falsch? 

Danke.


----------



## tobee (6. März 2007)

Was für ein Wert hat denn this.req wenn du es mit alert ausgibst?


----------



## versuch13 (6. März 2007)

tobee hat gesagt.:


> Was für ein Wert hat denn this.req wenn du es mit alert ausgibst?



obj XMLHTTPRequest

Nur innerhalb diesem Teil wird mir nichts ausgegeben:


```
if(this.req.readyState==4) {
				if (this.req.status == 200) {
					var e = document.getElementById(element);
					e.innerHTML = this.req.responseText;
				}
			}
```

Und this.req hat dort keinen Wert.


----------



## Quaese (7. März 2007)

Hi,

*this* in *onreadystatechange* hat einen anderen Kontext und somit Gültigkeitsbereich. D.h. *this* 
"zeigt" beim Aufruf der Funktion nicht mehr auf das Ajax-Objekt - testen kannst Du das, indem Du 
es mit *alert* ausgeben lässt.

Als Lösung kannst Du in der Funktion *updateElement* eine Variable deklarieren und ihr *this* zuweisen. 
Damit arbeitest Du dann in der *onreadystatechange*-Funktion.

```
AjaxRequest.prototype.updateElement = function(method,url,element) {
  var objThis = this;
  this.req.open(method,url,true);
  this.req.onreadystatechange = function() {
    if(objThis.req.readyState==4) {
      if (objThis.req.status == 200) {
        var e = document.getElementById(element);
        e.innerHTML = objThis.req.responseText;
      }
    }
  }
  this.req.send(null);
}
```
Vielleicht hilft Dir das weiter.

Ciao
Quaese


----------



## versuch13 (7. März 2007)

Besten Dank! Funktioniert nun genauso wie ich mir das vorstellte.

Grüße


----------



## versuch13 (8. März 2007)

So, ich habe daran jetzt noch etwas weiter gearbeitet. Mit dem Ergebnis bin ich
bisher eigentlich ganz zufrieden. Es gibt noch kein Error handling, das kommt noch.

Ansonsten hätte ich gerne mal ein paar Meinungen dazu, Verbesserungsvorschläge, Kritik, Tipps und Anregungen.


```
function AjaxRequest(url,options) {    
        this.url = url;
        this.method = (options.method) ? options.method : 'GET';
        this.query = (options.query) ? options.query : null;
        this.func = (options.onComplete) ? options.onComplete : null;
        this.req = (window.XMLHttpRequest)    
                   ?    
                   new XMLHttpRequest()    
                   :    
                   ((window.ActiveXObject)    
                   ?    
                   new ActiveXObject("Microsoft.XMLHTTP")    
                   :    
                   false    
                   );     
    }

    AjaxRequest.prototype.doRequest = function() {
        this.req.open(this.method,this.url,true);    
        if(this.method == 'POST') {
            this.req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
        }
        var objThis = this;
        var func = this.func;
        this.req.onreadystatechange = function() {        
            if (objThis.req.readyState==4 && objThis.req.status == 200) {            
                if(func != null) {
                    func(objThis.req.responseText, objThis.req.responseXML);
                }
            }
        }    
        this.req.send(this.query);
    }    

    
    /* Beispiele doRequest */
    function ajaxPost() {
        var value = document.getElementById('name').value; /* input Element value */
        value = escape(value);
        var ajax = new AjaxRequest('test.php',{method:'POST',query:'test='+value,onComplete:handle});  
        ajax.doRequest();
    }
    function ajaxGet() {
        var ajax = new AjaxRequest('hallo.txt',{method:'GET',onComplete:handle});
        ajax.doRequest()
    }
    function handle(text, xml) {
        alert(text);
    }
```

Was ich gerne noch hätte, wäre die Möglichkeit eine Funktion in den Options zu übergeben die ausgeführt wird bis der Request erfolgreich ausgeführt wurde, nur weiß ich nicht wie ich das abfragen kann und die Funktion dann auch stoppen.

Ich stelle mir das so vor dass man z.B. per

```
{onRunning:progressIndicator}
```
die Funktion bestimmt, zum Beispiel eben eine Funktion welche eine kleine
Gif Animation abspielt, und diese solange ausgeführt.

*Edit:* Eine Lösung für die Status Anzeige ist mir eingefallen. Ich werde die Möglichkeit
geben eine "onStart" Funktion zu definieren geben. Dann könnte man zum Beispiel mit der
onStart Funktion eine Gif Animation einblenden und mit der onComplete Funktion einfach 
wieder ausblenden. Wenn es aber eine andere Möglichkeit gibt bin ich dafür dankbar.


----------

