michaelberger: Konstruktor/prototypes aufrufen

Hallo zusammen :),

Ich bin gerade dabei einen Chat zu programmieren. Den unten stehenden JS-Code hab ich auf einer Vorlage aus dem Internet aufgebaut. Dieser funktioniert leider noch nicht (Der Konstruktor wird nicht aufgerufen). Es sollen mehrere Instanzen von diesem Chat auf einer Seite ausgegeben werden. Die ganze Thematik mit den prototypes als Klassenersatz habe ich aber auch noch nicht ganz verstanden. Deswegen bin ich mir absolut nicht sicher, ob ich die Methoden richtig definiere und aufrufe. Im Quellcode soll nur der Konstruktor aufgerufen werden und von dort aus die anderen Methoden. Eine mögliche Fehlerquelle könnte sein, dass ich die die Instanzen so initialisiere:

  
<script type="text/javascript">  
  var chat_<?php echo $interlocutor; ?> = new Chat(<?php echo $interlocutor; ?>);  
</script>  

Das heißt die Initialisierung findet im <body> statt. Der Code durchläuft mit PHP eine Schleife die für jeden Gesprächspartner einen Chat erstellt.
Hat jemand eine Idee was das Problem ist, bzw. wie ich es lösen könnte?

  
 function Chat(i) {  
  
    this.interlocutor = i;  
    this.httpObject = null;  
    this.link = "";  
    this.timerID = 0;  
  
    this.UpdateTimer();  
  }  
  
  // Get the HTTP Object  
  Chat.prototype.getHTTPObject = function(){  
     if (window.ActiveXObject) return new ActiveXObject("Microsoft.XMLHTTP");  
     else if (window.XMLHttpRequest) return new XMLHttpRequest();  
     else {  
        alert("Your browser does not support AJAX.");  
        return null;  
     }  
  };  
  
  // Change the value of the outputText field  
  Chat.prototype.setOutput = function (){  
     if(this.httpObject.readyState == 4){  
        var response = this.httpObject.responseText;  
        var objDiv = document.getElementById("result_"+this.interlocutor);  
        objDiv.innerHTML += response;  
        objDiv.scrollTop = objDiv.scrollHeight;  
        var inpObj = document.getElementById("msg_"+this.interlocutor);  
        inpObj.value = "";  
        inpObj.focus();  
     }  
  };  
  
  // Change the value of the outputText field  
  Chat.prototype.setAll = function (){  
     if(this.httpObject.readyState == 4){  
        var response = this.httpObject.responseText;  
        var objDiv = document.getElementById("result_"+this.interlocutor);  
        objDiv.innerHTML = response;  
        objDiv.scrollTop = objDiv.scrollHeight;  
     }  
  };  
  
  // Implement business logic  
  Chat.prototype.doWork = function (){  
     this.httpObject = getHTTPObject();  
     if (this.httpObject != null) {  
        this.link = "http://localhost/src/message.php?interlocutor="+this.interlocutor+"&msg="+document.getElementById('msg_'+this.interlocutor).value;  
        this.httpObject.open("GET", link , true);  
        this.httpObject.onreadystatechange = setOutput;  
        this.httpObject.send(null);  
     }  
  };  
  
  // Implement business logic  
  Chat.prototype.doReload = function (){  
     this.httpObject = getHTTPObject();  
     if (this.httpObject != null) {  
        this.link = "http://localhost/src/message.php?interlocutor="+this.interlocutor;  
        this.httpObject.open("GET", link , true);  
        this.httpObject.onreadystatechange = setAll;  
        this.httpObject.send(null);  
     }  
  };  
  
  Chat.prototype.UpdateTimer = function () {  
     this.doReload();  
     this.timerID = setTimeout(this.UpdateTimer(), 5000);  
  };  
  
  
  Chat.prototype.keypressed = function (e){  
     if(e.keyCode=='13'){  
        this.doWork();  
     }  
  };  

  1. Hallo michaelberger,

    beim Überfliegen gesehen:

    Chat.prototype.setOutput = function (){

    Chat.prototype.setAll = function (){

    this.httpObject.onreadystatechange = setOutput;

    this.httpObject.onreadystatechange = setAll;

    ich glaube, da fehlt ein this. Kam da in der Konsole keine Fehlermeldung?

    Gruß, Jürgen

    1. Danke für den Hinweis. Inzwischen wird der Konstruktor ausgeführt. Keine Ahnung warum davor nicht. Leider aber werden setOutput und setAll trotzdem nicht ausgeführt.

    2. Chat.prototype.setOutput = function (){

      Chat.prototype.setAll = function (){

      this.httpObject.onreadystatechange = setOutput;

      this.httpObject.onreadystatechange = setAll;

      Wenn man hier dann this benutzt: Kann es dann sein, dass das this sich nicht mehr auf das Chat-Obhekt bezieht, sondern auf das HTTPObjekt?

      1. Wenn man hier dann this benutzt: Kann es dann sein, dass das this sich nicht mehr auf das Chat-Obhekt bezieht, sondern auf das HTTPObjekt?

        Ja, this ist die aufrufende Instanz und onreadystatechange, welchens dann aufgerufen wird, wird von dem Requestobjekt gerufen.
        Deine Instanz mit der du dann set... aufrufen willst, musst du dir irgendwo merken.

        Das this was JürgenB an manchen stellen vermisst hat fehlt an noch mindestens einer weiteren Stelle. Wie du die findest hat er ja auch schon erwähnt.

        1. Das this was JürgenB an manchen stellen vermisst hat fehlt an noch mindestens einer weiteren Stelle. Wie du die findest hat er ja auch schon erwähnt.

          Danke nochmal. Jetzt sollte ich alle this haben. An einer Stelle funktionierts immer noch nicht:

          if(this.httpObject.readyState == 4){

          Die variable httpObject ist undefined. Dabei wird sie doch vorher in doReload() gesetzt:

          this.httpObject = getHTTPObject();

          Außerdem funktioniert die UpdateTimer()-Methode nicht richtig:

           Chat.prototype.UpdateTimer = function () {  
               var objChat = this;  
               this.doReload();  
               this.timerID = setTimeout(objChat.UpdateTimer(), 5000);  
            };
          

          So wie ich das jetzt verstanden habe ruft sie sich immmer wieder selbst auf, aber ohne setTimeout.

          1. Ich poste nochmal den ganzen Code:

              
              function Chat(i) {  
                this.interlocutor = i;  
                this.httpObject = null;  
                this.link = "";  
                this.timerID = 0;  
                var objChat = this;  
              
                //this.UpdateTimer();  
                this.doReload();  
              
                //document.getElementById("send_"+this.interlocutor).onclick = objChat.doWork();  
                //document.getElementById("sender_"+this.interlocutor).onkeyup = objChat.keypressed(event);  
              }  
              
              // Get the HTTP Object  
               function getHTTPObject(){  
                 if (window.ActiveXObject) return new ActiveXObject("Microsoft.XMLHTTP");  
                 else if (window.XMLHttpRequest) return new XMLHttpRequest();  
                 else {  
                    alert("Your browser does not support AJAX.");  
                    return null;  
                 }  
              };  
              
              // Change the value of the outputText field  
              Chat.prototype.setOutput = function (){  
                 if(this.httpObject.readyState == 4){  
                    var response = this.httpObject.responseText;  
                    var objDiv = document.getElementById("result_"+this.interlocutor);  
                    objDiv.innerHTML = response;  
                    objDiv.scrollTop = objDiv.scrollHeight;  
                    var inpObj = document.getElementById("msg_"+this.interlocutor);  
                    inpObj.value = "";  
                    inpObj.focus();  
                 }  
              };  
              
              // Change the value of the outputText field  
              Chat.prototype.setAll = function (){  
                    var objChat = this;  
                 if(objChat.httpObject.readyState == 4){  
                    var response = this.httpObject.responseText;  
                    var objDiv = document.getElementById("result_"+this.interlocutor);  
                    objDiv.innerHTML = response;  
                    objDiv.scrollTop = objDiv.scrollHeight;  
                 }  
              };  
              
              // Implement business logic  
              Chat.prototype.doWork = function (){  
                 this.httpObject = getHTTPObject();  
                 if (this.httpObject != null) {  
                    var objChat = this;  
                    this.link = "http://localhost/src/message.php?interlocutor="+this.interlocutor+"&msg="+document.getElementById('msg_'+this.interlocutor).value;  
                    this.httpObject.open("GET", this.link , true);  
                    this.httpObject.onreadystatechange = objChat.setOutput;  
                    this.httpObject.send(null);  
                 }  
              };  
              
              // Implement business logic  
              Chat.prototype.doReload = function (){  
                 this.httpObject = getHTTPObject();  
                 if (this.httpObject != null) {  
                    var objChat = this;  
                    this.link = "http://localhost/src/message.php?interlocutor="+this.interlocutor;  
                    this.httpObject.open("GET", this.link , true);  
                    this.httpObject.onreadystatechange = objChat.setAll;  
                    this.httpObject.send(null);  
                 }  
              };  
              
              Chat.prototype.UpdateTimer = function () {  
                 var objChat = this;  
                 this.doReload();  
                 this.timerID = setTimeout(objChat.UpdateTimer(), 5000);  
              };  
              
              
              Chat.prototype.keypressed = function (e){  
                 if(e.keyCode=='13'){  
                    this.doWork();  
                 }  
              };
            
          2. if(this.httpObject.readyState == 4){

            Wenn der Code in der onreadystatechange-Funktion steht bezieht sich this wieder aufs Ajax-Objekt

            Chat.prototype.UpdateTimer = function () {

            var objChat = this;
                 this.doReload();
                 this.timerID = setTimeout(objChat.UpdateTimer(), 5000);
              };

            Hier dürfte das gleiche passieren, this bezieht sich beim ersten mal noch auf das Chat-Objekt, beim zweiten Aufruf via setTimeout allerdings auf das window-Objekt. Nebenbei, warum setTimeout und nicht einmalig setInterval?  
              
            MfG  
            bubble
            
            1. if(this.httpObject.readyState == 4){
              Wenn der Code in der onreadystatechange-Funktion steht bezieht sich this wieder aufs Ajax-Objekt

              Chat.prototype.UpdateTimer = function () {

              var objChat = this;
                   this.doReload();
                   this.timerID = setTimeout(objChat.UpdateTimer(), 5000);
                };

              
              > Hier dürfte das gleiche passieren, this bezieht sich beim ersten mal noch auf das Chat-Objekt, beim zweiten Aufruf via setTimeout allerdings auf das window-Objekt. Nebenbei, warum setTimeout und nicht einmalig setInterval?  
              >   
              > MfG  
              > bubble  
                
                
              Danke für den Tipp. Hab jetzt  
              `setInterval(objChat.doReload(), 5000);`{:.language-javascript}  
              in den Konstruktor eingebaut.  
                
              Wie kann ich ihm den das Chat-Objekt übergeben?  
              Muss das so aussehen oder geht das auch einfacher:  
                
              `this.httpObject.onreadystatechange = function() {objChat.setOutput(objChat)};`{:.language-javascript}
              
              1. Wie kann ich ihm den das Chat-Objekt übergeben?
                Muss das so aussehen oder geht das auch einfacher:

                this.httpObject.onreadystatechange = function() {objChat.setOutput(objChat)};

                für if(this.httpObject.readyState == 4){ brauchst du doch garnicht das Chat-Objekt.
                this spiegelt in dem Fall ja schon das httpObject wider.
                if(this.readyState == 4){ sollte des Rätsels Lösung sein.

                MfG
                bubble