PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Javascript: Problem mit XMLHttpRequest im Objekt


Kampf-Sushi
2006-06-04, 20:01:20
Ich versuche gerade verzweifelt ein XMLHttpRequest komplett innerhalb eines Javascript Objektes zu machen.
Global funktionierts tadellos, aber sobald ich versuch es in einer js-function zu kapseln...

Beispielcode genommen von hier (http://developer.mozilla.org/de/docs/AJAX:Getting_Started) und aufs wesentliche gekürzt:

function MeineKlasse() {
this.http_request = false;

this.macheRequest = function(url) {
this.http_request = false;
this.http_request = new XMLHttpRequest();

if (this.http_request.overrideMimeType) {
this.http_request.overrideMimeType('text/xml');
}

this.http_request.onreadystatechange = this.alertInhalt;
this.http_request.open('GET', url, true);
this.http_request.send(null);

}

function alertInhalt() {
if (this.http_request.readyState == 4) {
if (this.http_request.status == 200) {
var xmldoc = http_request.responseXML;
var root_node = xmldoc.getElementsByTagName('root').item(0);
alert(root_node.firstChild.data);
} else {
alert('Bei dem Request ist ein Problem aufgetreten.');
}
}
}
}

meinObj = new MeineKlasse();
meinObj.macheRequest('test.xml');


Besonders seltsam ist: Er meldet mir zwar die Syntaxfehler in der XML-Datei, aber bei folgenden Code bekomm ich nichtmal einen alert:


function alertInhalt() {
if (this.http_request.readyState == 4) {
if (this.http_request.status == 200) {
alert('zu huelf!');
}
}
}


Ich teste mit Firefox.
Mir wuerde das vorerst auch reichen wenns schonmal im Firefox laeuft. Bei anderen Browsern kann ich dann spaeter schaun.

clm[k1]
2006-06-04, 20:47:19
Sollte man eine klasse nicht mit 'class' definieren? :|
Und sollte man nicht auch erst die klassen-member definieren bevor man mit 'this' darauf zu greift?

also etwa so:


class MyClass {
var httpRequest = null;

function makeRequest() {
this.httpRequest = new XMLHttpRequest();
...
}

...
}

var myObject = new MyClass();
myObject.makeRequest();



just my 2 cent
clm[k1]

Sephiroth
2006-06-04, 20:57:18
'clm[k1]'[/POST]']Sollte man eine klasse nicht mit 'class' definieren? :|
Und sollte man nicht auch erst die klassen-member definieren bevor man mit 'this' darauf zu greift?

also etwa so:


class MyClass {
var httpRequest = null;

function makeRequest() {
this.httpRequest = new XMLHttpRequest();
...
}

...
}

var myObject = new MyClass();
myObject.makeRequest();



just my 2 cent
clm[k1] class gibt es erst in JavaScript 2.0 und Firefox 2.0 kann erst JavaScript 1.6 ;)

das
this.http_request.onreadystatechange = this.alertInhalt;
geht jedenfalls erstmal nicht (alertInhalt wird gar nicht gefunden ergo nicht aufgerufen)
probier mal
this.http_request.onreadystatechange = alertInhalt;

weiter hab ich noch nicht geschaut

Sephiroth
2006-06-04, 21:11:51
so sollte es gehen

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" language="javascript">

function MeineKlasse() {
var http_request = false;

this.macheRequest = function (url) {
http_request = false;
http_request = new XMLHttpRequest();

if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/xml');
}

http_request.onreadystatechange = alertInhalt;
http_request.open('GET', url, true);
http_request.send(null);
}

function alertInhalt() {
try{
if (http_request.readyState == 4) {
if (http_request.status == 200) {
var xmldoc = http_request.responseXML;
var root_node = xmldoc.getElementsByTagName('root').item(0);
alert(root_node.firstChild.data);
} else {
alert('Bei dem Request ist ein Problem aufgetreten.');
}
}else{
alert(http_request.readyState);
}
}catch(e){
alert(e);
}
}
}

function makeRequest(aName) {
var meinObj = new MeineKlasse();
meinObj.macheRequest(aName);
}
</script>
</head>
<body>
<span
style="cursor: pointer; text-decoration: underline"
onclick="makeRequest('test.xml')">
Make a request
</span>
</body>
</html>

Das Problem bei deinem Code war, dass du in den Funktionen ebenfalls this verwendest hattest, doch das bezoieht sich da dann nicht auf das gewünschte Objekt, sondern nur auf die Funktion.
Beispiel
function test(){
var foo = "foo";
testen();

function testen() {
this.foo = "bar";
alert(foo); // ausgabe: "foo"
alert(this.foo); // ausgabe: "bar"
}
}

Kampf-Sushi
2006-06-04, 21:25:57
Sephiroth[/POST]']
geht jedenfalls erstmal nicht (alertInhalt wird gar nicht gefunden ergo nicht aufgerufen)
Stimmt, danke. (Das kommt vom Copypaste ;))
Das erklaert schonmal das seltsame Verhalten das ich im unterem Abschnitt erwaehnte.

Also kann man davon ausgehen dass die XML-File korrekt geladen wird.

Mein aktueller Code:

function MeineKlasse() {
this.http_request = false;

this.macheRequest = function(url) {
this.http_request = false;
this.http_request = new XMLHttpRequest();

if (this.http_request.overrideMimeType) {
this.http_request.overrideMimeType('text/xml');
}

alert(this.http_request); //Output: [object XMLHttpRequest]
this.http_request.onreadystatechange = this.alertInhalt;
this.http_request.open('GET', url, true);
this.http_request.send(null);
}

this.alertInhalt = function() {
alert(this.http_request); //Output: undefined
if (this.http_request.readyState == 4) {
if (this.http_request.status == 200) {
alert("zu huelf!");
}
}
}
}

meinObj = new MeineKlasse();
meinObj.macheRequest('test.xml');


Was die Alerts ausgeben steht jeweils im Kommentar dahinter.
In der Methode macheRequest() scheint die Eigenschaft this.http_request korrekt gesetzt zu werden. (Siehe erstes Alert);

Die Methode alertInhalt() scheint aber ploetzlich nichts mehr von Eigenschaft zu wissen.

Sephiroth
2006-06-04, 21:29:58
Kampf-Sushi[/POST]']
Was die Alerts ausgeben steht jeweils im Kommentar dahinter.
In der Methode macheRequest() scheint die Eigenschaft this.http_request korrekt gesetzt zu werden. (Siehe erstes Alert);

Die Methode alertInhalt() scheint aber ploetzlich nichts mehr von Eigenschaft zu wissen.
siehe zweiten Beitrag von mir :biggrin:

clm[k1]
2006-06-04, 21:47:42
Sephiroth[/POST]']class gibt es erst in JavaScript 2.0 und Firefox 2.0 kann erst JavaScript 1.6 ;)


:ugly: ich weiß schon warum ich JavaScript meide... (was soll man auch von einer Scriptsprache halten, die keine getypten variablen hat, aber den Operator + überlädt sodass man damit addieren und konkatenieren kann :ucrazy: )

Naja, egal ...wieder was dazu gelernt.


clm[k1]

Kampf-Sushi
2006-06-04, 21:49:44
Sephiroth[/POST]']siehe zweiten Beitrag von mir :biggrin:
Musste den ja ersteinmal sehen und nachvollziehen :).

So funktioniert jedenfalls alles, danke schoen fuer die Hilfe.

Trap
2006-06-04, 21:58:20
'clm[k1]'[/POST]']was soll man auch von einer Scriptsprache halten, die keine getypten variablen hat, aber den Operator + überlädt sodass man damit addieren und konkatenieren kann :ucrazy: )

Das gilt auch für Python.

Javascript ist sicher die am meisten missverstandene Programmiersprache, so viel falsche Beschreibungen wie über Javascript findet man zu keiner anderen Programmiersprache.

HellHorse
2006-06-04, 22:04:59
Trap[/POST]']Das gilt auch für Python.

Javascript ist sicher die am meisten missverstandene Programmiersprache, so viel falsche Beschreibungen wie über Javascript findet man zu keiner anderen Programmiersprache.
FULL ACK.
JS, Python, Smalltalk und Konsorten sind sehr wohl typisiert. Bloss einfach dynamisch und nicht statisch.

Kampf-Sushi
2006-06-04, 23:02:44
Noch eine Sache:
Urspruenglich wollte ich die HTTP-Requests ja in ein Array packen um auch mehrere Requests parallel ausfuehren zu koennen. Das Problem an der Sache ist dann nur dass die responseHandler Methode nicht ohne weiteres parametisiert werden kann.

Im Web laß ich vom Lösungsvorschlag eine function drum herum zu kapseln:

http_request.onreadystatechange = function() {alertInhalt;};


Das funktioniert aber leider wiedermal nur solange ich globale Methoden benutze, weil wenn ich

http_request.onreadystatechange = function() {this.alertInhalt;};

benutzen wuerde, muesste er beim this sich wieder auf die Kapselungs-Methode beziehen.

Loesungsvorschlag anyone?

Sephiroth
2006-06-04, 23:11:06
Kampf-Sushi[/POST]']Noch eine Sache:
Urspruenglich wollte ich die HTTP-Requests ja in ein Array packen um auch mehrere Requests parallel ausfuehren zu koennen. Das Problem an der Sache ist dann nur dass die responseHandler Methode nicht ohne weiteres parametisiert werden kann.

Loesungsvorschlag anyone? Wie wäre es mit Eigenschaften für dein Objekt, welche als Parameter für alertInhalt() genutzt werden könnten? so mal spontan ...

Javascript ist sicher die am meisten missverstandene Programmiersprache
full ack :(

Kampf-Sushi
2006-06-06, 00:34:52
Ich bin echt kurz davor saemmtliche "OO"-Versuche bzgl. Javascript ueber den Haufen zu schmeissen.
Anfangs fand ich das OO-Konzept von js "Interessant".
Mittlerweile find ich es nur noch "ICH SCHLAG DICH DU...".

Zu meinen Problem:

function MeineKlasse() {
var http_request = false;

this.macheRequest = function(url) {
http_request = new XMLHttpRequest();

if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/xml');
}

http_request.onreadystatechange = this.alertInhalt;
http_request.open('GET', url, true);
http_request.send(null);
}

this.alertInhalt = function(parameter) {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
//GRMLHMPTNARFFFF!!!!!!!!!!
this.MACHWASVERDAMMTNOCHMAL('fu js'); //...is not a function
MACHWASVERDAMMTNOCHMAL('fu js'); //...is not defined
}
}
}

this.MACHWASVERDAMMTNOCHMAL = function(parameter) {
alert(parameter);
}
}

meinObj = new MeineKlasse();
meinObj.MACHWASVERDAMMTNOCHMAL('hier gehts'); //... no problemo
meinObj.macheRequest('test.xml');


Ich moechte einfach nur die Methode MACHWASVERDAMMTNOCHMAL() innerhalb der http_request Verarbeitung aufrufen.
Was die alerts jeweils fuer Fehlermeldungen auspucken steht jeweils dahinter.

Wenn mir irgendwer erklaeren koennte wie ich das hinbekommen kann, waere das super.
Falls nicht kann ich das ganze OO-Zeug fuer dieses Projekt in die Toilette kippen.

MfG: leicht gereiztes Sushi

Trap
2006-06-06, 01:16:24
Ich hab noch nie JavaScript programmiert und hab es auch nicht getestet:

this.alertInhalt = function(parameter) {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
this.funtionToCall();
}
}
}

this.MACHWASVERDAMMTNOCHMAL = function(parameter) {
alert(parameter);
}

this.alertInhalt.functionToCall = this.MACHWASVERDAMMTNOCHMAL;

Geht das?

Kampf-Sushi
2006-06-06, 01:28:24
Trap[/POST]']Geht das?
So in der Form nicht, aber ich verstehe worauf du hinaus willst...
Hm.. ja.. probier ich danach nochmal so. Erstmal das Ding hier zuende machen wo ich grad dran werkel.

Kampf-Sushi
2006-06-23, 00:05:07
Hi!
Hab das Ganze erstmal n Weilchen ruhen lassen und mich eben nochmal kurz dran gesetzt.
Wenn es jemanden interessiert wie es am Ende funktioniert:


function MeineKlasse() {
var http_request = false;

this.macheRequest = function(url) {
http_request = new XMLHttpRequest();

if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/xml');
}

var callingObj = this;
var parameter = 'hallo';
http_request.onreadystatechange = function() {callingObj.handleResponse(parameter);};
http_request.open('GET', url, true);
http_request.send(null);
}

this.handleResponse = function(parameter) {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
this.test(parameter);
}
}
}

this.test = function (parameter) {
alert(parameter);
}

}

meinObj = new MeineKlasse();
meinObj.macheRequest('test.xml');


Klappt sogar mit Parametern wie man sieht.

MfG Sushi