ugrás a tartalomhoz

onreadystatechange parameteratadas

khiraly · 2007. Május. 19. (Szo), 11.26
Sziasztok!

Van egy fuel objektumom:

function fuel() {
  this.date  = new Array("20060101", "20060213", "20060303");
  this.sum   = new Array(12340, 3450, 0);
  this.place = new Array("OMV", "Mol", "Jet");
}
Ezt szeretnem egy olyan fuggvenybol modositani, amit az oldalon egy textarea elhagyasa (onblur) aktival*.

Tehat ha valakimodositott a textarean, akkor a szervertol kapjon a javascript egy date, sum, place harmast es ezt irja bele a fuel objektumba.

A PROBLEMA: nem tudom a fuel objektumot odaadni a feldolgozo fuggvenyemnek, magyaran:

function fuel_from_server() {
  xmlhttp.open("GET", "../cgi-bin/serv_fuel.py", true);
  xmlhttp.onreadystatechange = fuel_processing(fuel);
  xmlhttp.send(null);
}
Itt a fuel_processing(fuel) nem mukodik. nem tudok parametert atadni (firefox alatt).
Vagyis mukodik de csak a readyState == 1-ig jut el, a 2,3,4 mar nem fut le.

KERDES: Hogyan lehet a hivo fuggveny objektumat elerni a fuel_processing() fuggvenybol?
Csak ugy tudommost megoldani, hogyha a fuel fuggvenyt peldanyositom es globalis objektumot csinalok belole. Elegansabbmegoldas letezik?

FOLYAMATABRA (amit meg szeretnek oldani):
felhasznalo modosit egy bejegyzest->szerver valaszkent kuld egy 3 elemu tombot (date, sum, place)-> a megkapott adatot egy mar letezo objektum tulajdonsagaihoz kellene illeszteni.

*: ((btw, tudja valaki hogyan kell elkapni, hogyha valaki entert ut egy textarean?))

Remelem ertheto, es nem lett tul bonyolultan megfogalmazva.
 
1

nem adhatsz meg paramétereket

bado · 2007. Május. 19. (Szo), 13.34
http://developer.mozilla.org/en/docs/AJAX:Getting_Started -n találtam:

"no parameters passed, because you're simply assigning a reference to the function, rather than actually calling it."

bado
2

Paraméteres eseménykezelés

vbence · 2007. Május. 19. (Szo), 14.03
Ha paraméterrel szeretnél ellátni egy eseménykezelőt, akkor a closure lesz a te barátod. Röviden:

var fuel = akarmi;
xmlhttp.onreadystatechange = function (event) { fuel_rocessing(event, fuel); }
Könnyen belátható, hogy a te sorod:
 xmlhttp.onreadystatechange = fuel_processing(fuel);
egyszerűen lefuttatja a fuel_processing(fuel) függvényt, és a hívás eredményét állítja be, mint eseménykezelőt, úgyhogy egyszer le fog futni a függvényed (ami a readystate=1 -ként értékelsz), a valódi eseményeket pedig nem kezeli semmi (mivel nincs a függvénynek visszatérő értéke).


Például ebben a témában is fellelhető:
http://weblabor.hu/forumok/temak/17482

De ha keresel a bűvös szóra a Weblabor keresőjében, akkor még több dolog is eljőjön.

Amúgy abban az esertben, hogyha csak egyetlen fule-frissítész hajtasz végre egyidőben nyugodtan dolgozhatsz window.fulel-lal, ezt minen eseménykezelő eléri closure nélkül is.
3

szinkronizalas, timout vagy mi?

khiraly · 2007. Május. 19. (Szo), 14.16
koszi szepen a valaszt!
A closure az nalad a {} kapcsos zarojelek kozotti resz, vagy valami nyelvi elem?

Van egy masik problemam is:
A kis szkriptem valaszol egy xml-lel (2005, 1234, mol) amit beirok (egyelore globalis) fuels objektumomba. A problema, hogy a megjelenites hamarabb tortenik mint az objektum frissitese (gondolom van valami kesleltetes a halon, megha localhost is).

Ha egy alert() hivast beteszek (tehat manualisan addig megszakitom a javascript futasaat), akkor a frissitett fuels objektum jelenik meg.

Erre van valami 5leted?

Ime a kod:
function tank_input() {
  var v = document.getElementById("tank").value;
  md = document.getElementById('tank_result');
  md.className = "on";
  fuel_from_server();
  //alert("ha ez be van kapcsolva, akkor a frissitett objektum jelenik meg");
  var html_snippet = "<table>";
  for (var i = 0; i < fuels.date.length; i++) {
    html_snippet += "  <tr><td>"+fuels.date[i]+"</td><td>"+fuels.sum[i]+"</td><td>"+fuels.place[i]+"</td></tr>";
  }
  html_snippet += "</table>";
  md.innerHTML = html_snippet;
}

function fuel_from_server() {
  xmlhttp.open("GET", "../cgi-bin/serv_fuel.py", true);
  xmlhttp.onreadystatechange = fuel_processing;
  xmlhttp.send(null);
}

function fuel_processing() {
  if (xmlhttp.readyState == 4) {
    var xmlResponse = xmlhttp.responseXML;
    // obtain the XML's document element
    xmlRoot = xmlResponse.documentElement;
    // update the fuels object
    fuels.date.push(xmlRoot.getElementsByTagName("date").item(0).firstChild.data);
    fuels.sum.push(xmlRoot.getElementsByTagName("sum").item(0).firstChild.data);
    fuels.place.push(xmlRoot.getElementsByTagName("place").item(0).firstChild.data);
  }
 // else { alert("mostmar: "+xmlhttp.readyState);}
}

function fuel() {
  this.lock  = 0;
  this.date  = new Array("20060101", "20060213", "20060303");
  this.sum   = new Array(12340, 3450, 0);
  this.place = new Array("OMV", "Mol", "Jet");
  this.date.push("206666666");
  this.sum.push("------------ ");
  this.place.push("-----------");
}
4

Megjeleítő rész csak a válasz után fusson le

vbence · 2007. Május. 19. (Szo), 16.13
Van a tank_input függvényed. Ebben elindítod az AJAX hívást. Logikus, hogy csak az adotok elérése (és feldolgozása) után akarod módosítani a dokumentum tartalmát. Azt javasolom, hogy a
var html_snippet = "<table>";
  for (var i = 0; i < fuels.date.length; i++) {
    html_snippet += "  <tr><td>"+fuels.date+"</td><td>"+fuels.sum[i]+"</td><td>"+fuels.place[i]+"</td></tr>";
  }
  html_snippet += "</table>";
  md.innerHTML = html_snippet;
részt illeszt be egy új függvénybe, mondjuk [i]doc_refresh, és ezt hívd meg a fuel_processing végén. Ilyenkor csak akkor frissül majd a kiírás, amikor az új adatok már fel vannak dolgozva.

Ha AJAX-ot csinálsz, figyelj az első A betűre! Csinálhatsz SJAX-ot is. Akkor csak egyetlen sort kell módosítanod:
xmlhttp.open("GET", "../cgi-bin/serv_fuel.py", false);
ilyenkor áll a szkript, amég a válasz nem érekzik meg. Ez a legtöbb browserben csúnya, fagyás szerű állapotot jelent a várakozás során. Csak azért írom le ezt a lehetőséget, hogy jobban lásd a különbséget.
Ne várj szikronizálást, ha egyszer az AJAX melett döntöttél.
5

szinkronizalas

khiraly · 2007. Május. 20. (V), 20.21
Ha most nem is (koszi a onreadystatechange-nel a parameteres hivasos tippet: function (event) { ...), de kesobb biztosan kell majd nekem valamifele szinkronizalas. Lattam neten vlamifele esemenykezelessel megoldani, de nem igazan ertem.

Mondok egy kepzeletbeli peldat:
van egy ajaxos vasarlos oldalam, a vasarlas es az aruk kivalasztasa is ajax segitsegevel tortenik. A felhasznalo a kosarba tesz egy arut (amit a szerver oldalon is lekezel), majd nagyon gyorsan (<1s) a vasarlas befejezese (checkout) gombra kattint. Vajon a legutolso arut is meg fogja venni, vagy meg az eggyel elobbi alapotot vasarolja?

Szoval vannak peldak ahova kell szinkronizalas (es majd nekem is kelleni fog, a fenti peldara teljesen analog modon).

Van erre valami jo tipped, vagy esetleg leirasod?

Khiraly
6

Nem kell mindent szinkronizálni

vbence · 2007. Május. 21. (H), 00.52
A folyamat kb ilyen lehet:

- a vásárló megnyomja a gombot
- a javascript legyártja a kérés paramétereit (xmlhttp)
- http hívás (tcp egyeztetés)
- a szerver elindítja a (php) szkriptet
- a szkript elvégzi a változásokat az adatbázisban
- a szkript elkészíti a választ az AJAX kérésre
- a válasz megérkezik
- az eseménykezelő javascript elvégzi a módosításokat DOM (vagy innerHTML) segítségével

A lényeg, hogy a kliens -> szerver üzenetküldés villámgyors. Nem akarok hülyeséget mondani, de ha az egész idő kb 1 másodperc, akkor az első két tizedmásodpecben megtörténik az üzenetküldés és a feldolgozás.

De a fenti esetnél maradva, ha valaki betesz valamit a kosárba, és nem várja meg, hogy megjelenjen, hanem egyből továbbnyomja, az ne csodálkozzon, ha nem lesz benne az elem :)