Autor Zpráva
xxxObiWan
Profil
Ahoj,
snažím se si v JS vytvořit pro zjednodušení práce s ajaxem objekt Ajax, který by se používal takto:
  var Ajax1 = new Ajax();
  Ajax1.setDivId('divObsah');   //výsledek se vloží do divu s id="divObsah"
  Ajax1.send("nejaka_stranka.html", "promenna1=ahoj&promenna2=nazdar");   //odeslání požadavku: Ajax.send(nazev_stranky, promenne)


Zatím na to jdu takhle
  function Ajax(){
          // KONSTRUKTOR //
          this.method = 'POST';
          this.divId = '';

          if( window.ActiveXObject ) this.HttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
          else this.HttpRequest = new XMLHttpRequest();
          
          // FUNKCE //
          this.setDivId = function(newDivId){
                            this.divId = newDivId;
                            return true;
          };
          
          this.send = function(url, vars){
                            this.HttpRequest.open(this.method, url, true);
                            this.HttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                            this.HttpRequest.onreadystatechange = this.prijmiData;
                            this.HttpRequest.send(vars);          
          };
          
          this.prijmiData = function(){
                            document.getElementById(this.divId).innerHTML = 'loading...';
                            if( this.HttpRequest.readyState==4 ){
                                if( this.HttpRequest.status==200 ){
                                    document.getElementById(this.divId).innerHTML = this.HttpRequest.responseText;
                                }
                                else{
                                    document.getElementById(this.divId).innerHTML = 'Chyba '+this.HttpRequest.status+'.';
                                }
                            }          
          };
  };

ale z nějakého neznámého důvodu jsou ve funkci prijmiData všechny proměnné this.cokoliv prázdné. Nevíte pls co s tím?

Díky
_es
Profil
xxxObiWan:
V 18. riadku priraďuješ do vlastnosti HttpRequest.onreadystatechange vytvoreného objektu vlastnosť toho istého objektu prijmiData, ktorá má vtedy hodnotu undefined.
Ten kus kódu od 22. riadku treba presunúť pred to priradenie.
Chamurappi
Profil
Reaguji na _es:
Neřekl bych, že tohle bude příčina, protože metoda prijmiData se vytvoří při vytváření objektu a metoda send, která tuto metodu přiřazuje do události, se volá až později. Také popsaný projev problému tomu moc neodpovídá, z popisu xxxObiWana plyne, že se prijmiData volá, akorát tam je špatné this


Reaguji na xxxObiWana:
… a to this bude nejspíš instance XMLHttpRequestu.

Nevíte pls co s tím?
Normálně slušně česky poprosit neumíš?
_es
Profil
Chamurappi:
… a to this bude nejspíš instance XMLHttpRequestu.

this bude novovytvorený objekt s konštruktorom Ajax.
Objekt XMLHttpReaquestu bude Ajax1.HttpRequest.
Možno tam bude nejakých podivností viac.

Aha, už som to pochopil:
Asi treba v tej funkcii this.HttpRequest zameniť len za this alebo nie, (teda v tej vlastnosti prijmiData)?
Witiko
Profil
Tohle by nezpůsobilo zachování daného this? Lexical closure.

          this.send = function(url, vars){
                            this.HttpRequest.open(this.method, url, true);
                            this.HttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                            this.HttpRequest.onreadystatechange = (function(){function() {this.prijmiData()}}).apply(this);
                            this.HttpRequest.send(vars);          
          };


Drycoded, připojené funkci je předán správný this, nicméně si nejsem jistý, jestli ho HttpRequest při triggernutí eventu nepřepíše.
Pokud by nefungovalo, tohle by mělo již na 100%:

          this.send = function(url, vars){
                            this.HttpRequest.open(this.method, url, true);
                            this.HttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                            this.HttpRequest.onreadystatechange = (function(that){function() {that.prijmiData()}})(this);
                            this.HttpRequest.send(vars);          
          };


Zdá se, že this.HttpRequest.onreadystatechange = this.prijmiData; způsobí jen vytvoření reference na danou prijmiData funkci, this je předané samotným eventem, v tomto případě objektem HttpRequest. Jedná se o stejný problém, se kterým jsem se potýkal v topicu Propašování nové funkce k prototypu libovolného elementu.

Element.prototype.alert = window.alert;
Element.prototype.alert();


window.alert zde pouze slouží k předání reference a this je v tomto případě Element.prototype. K samotnému předání window jako this by došlo pouze v případě volání funkce, viz. window.alert();
Chamurappi
Profil
Reaguji na Witika:
Tohle by nezpůsobilo zachování daného this?
Na první pohled bych řekl, že v obou kódech do onreadystatechange přiřazuješ undefined, protože volané funkce nic nevracejí.
S doplněným returnem se ten první kód bude chovat stejně jako bez lexikálního uzávěru.
Witiko
Profil
Správně, zapomněl jsem na return. V tom případě tohle by mělo být řešení:

          this.send = function(url, vars){
                            this.HttpRequest.open(this.method, url, true);
                            this.HttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                            this.HttpRequest.onreadystatechange = (function(that){return function() {return that.prijmiData()}})(this);
                            this.HttpRequest.send(vars);          
          };

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0