Toon posts:

[ajax] xmlhttp object undefined

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik wil zelf een javascript class schrijven om dynamisch javascript bestanden te laden.

Nu heb ik de onderstaande class geschreven:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
var fileObject = {
    path        : './',
    sequence    : 0,
    cache       : new Boolean(true),
    busy        : new Boolean(false),
    files       : null,
    head        : null, 
    url         : null,
    http        : null,
    start       : function(){
        this.head = document.getElementsByTagName('head')[0];
        this.http = this.getHTTPObject();
        this.loadFile();
    },
    loadFile    : function(){       
        file = this.getFile();
        if(file!=false && this.busy==false && this.http){
            this.url = this.path+file;
            this.http.open("GET", this.url, false);         
            this.http.onreadystatechange = this.handleFile;
            this.busy = true;
            this.http.send(null);
        }
        file = null;
        this.url = null;
    },
    handleFile  : function(){
        alert(this.http); <-- hier gaat het dus fout!
        if(this.http.readyState==4){
            if(this.http.status==200){
                if(this.http.statusText.indexOf('error')!=-1){
                    var el = document.createElement('script');
                    el.setAttribute('type','text/javascript');
                    el.setAttribute('id','jsScript'+this.sequence);
                    this.head.appendChild(el);
                    document.getElementById('jsScript'+this.sequence).text += this.http.responseText;
                    el = null;
                    this.sequence++;
                }
                this.busy = false;
                this.loadFile();
            }else if(this.http.status==404){
                alert('Extern javascript "' + this.url + '" kon niet worden geladen!');
            }else{
                alert('Onbekende fout opgetreden: ' + this.http.status);
            }
        }       
    },
    getFile     : function(){
        if(this.files.constructor.toString().indexOf('Array')!=-1 || 
           this.files.constructor==Array){
            if(this.files.length>0){
                return this.files.shift();
            }else{
                return false;
            }
        }else{
            return false;
        }
    },
    getHTTPObject: function(){
        var xmlhttp;
        /*@cc_on
        @if(@_jscript_version >= 5)
            try{
                xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
            }catch(e) {
            try {
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
          } catch (E) {
            xmlhttp = false;
          }
        }
        @else
            xmlhttp = false;
        @end @*/
        if(!xmlhttp && typeof XMLHttpRequest != 'undefined'){
            try{
                xmlhttp = new XMLHttpRequest();
            }catch(e) {
                xmlhttp = false;
            }
        }
        return xmlhttp;
    }   
};


En dit wordt op de volgende manier aangeroepen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!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>Untitled Document</title>
<script type="text/javascript" src="/js/fileobject.js"></script>
<script type="text/javascript">
fileObject.path  = '/js/';
fileObject.files = new Array('test.js','test2.js');
fileObject.start();
</script>
</head>

<body>
<script type="text/javascript">
if(window.test){
    test('Test 1');
    test2('Test 2');
}else{
    alert('functions do not exist!');
}
</script>
</body>
</html>


Het gaat dus fout bij de functie "handleFile". (bij regel 28).
Daar wordt de this.http variabele opeens undefined.

Kan iemand mij uitleggen waarom dit gebeurt?

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 18:58

crisp

Devver

Pixelated

Je onreadystatechange handler wordt in de global scope uitgevoerd; als je een handle wilt hebben naar je http object-instance dan zal je een global moeten gebruiken of expliciet scopen mbv een closure.

[ Voor 5% gewijzigd door crisp op 22-12-2006 10:42 ]

Intentionally left blank


Verwijderd

Topicstarter
Ik ben nog niet zo heel lang met javascript en classes bezig, mijn excuses als dit domme vragen zijn :)

Maar this.http is toch juist een globale variabele binnen de class?

En wat is een closure?

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 18:58

crisp

Devver

Pixelated

Verwijderd schreef op vrijdag 22 december 2006 @ 10:45:
Ik ben nog niet zo heel lang met javascript en classes bezig, mijn excuses als dit domme vragen zijn :)

Maar this.http is toch juist een globale variabele binnen de class?
Er is no such thing als een global binnen een class :P this.http is een referentie naar een (local) property van je instance. Het 'this' keyword verwijst naar het object dat de scope definieert, bij de onreadystatechangehandler is dat het window object.
En wat is een closure?
Door een extra scope te introduceren kan je variabelen 'vasthouden' en dus ook mbv call of apply een functiecall doen in de scope van een ander object:
JavaScript:
1
2
3
var handler = this.handleFile;
var self = this;
this.http.onreadystatechange = function() { self.call(handler); }

Intentionally left blank