AJAX kommunikáció prototype-pal
ajax, hogyan, prototype
A prototype igazán a kezünk alá dolgozik sok-sok mindenben. Ezek közül most vizslassuk meg, hogy mit tud AJAX ügyben. Egy egyszerű kis példán fogunk végigfutni. Adott egy link és ha rákattintunk akkor a szerver véletlenszerűen kiválaszt egy képet és visszaküldi nekünk.
Alapozunk
Html
A html head részében szükségünk lesz a prototype library-ra, szóval:
<script type="text/javascript" src="./prototype.js"></script>
Kiindulásként a lapon szükségünk lesz egy linkre és egy dobozkára amiben meg fog jelenni a szervertől kapott kép. Ha nem akarjuk, hogy az oldal többi része ide-oda csuszkáljon az adatok fogadása alatt, akkor jó ha a CSS-ben fixáljuk az elemek magasságát. Így akár benne van a válaszul érkezett kép, akár nincs ugyanakkora helyet foglal el.
<div id="ptypeajax"> <div id="ptakep">ide jön majd a kép</div> <a href="#" id="amilinkunk">Kérek a szervertől egy képet!</a> </div>
Az üres link # nem éppen a legoptimálisabb megoldás, mivel így a javascriptet nem ismerő böngészők, mint például a keresőrobotok kizáródnak az alkalmazásból, de erről majd máskor beszélünk.
JavaScript
Itt egyenlőre csak arról gondoskodunk, hogy az oldal betöltése után legyen valaki aki figyeli, hogy mikor kattintanak a linkünkre. és ha ez netán bekövetkezne akkor hívja meg az adjUjKepet függvényünket. Az első observer azért kell, mert e nélkül a második observer nagy valószínűséggel még a DOM felépülése előtt lefutna, de a DOM nélkül ugye nem fogja megtalálni a mi linkünket.
Event.observe(window, "load", ptaInit);
function ptaInit(){
aMiLinkunk = $("amilinkunk");
Event.observe(aMiLinkunk, "click", adjUjKepet);
}
AJAX lekérés
A prototype library két eszközt is a kezünkbe ad AJAX kommunikáció lebonyolítására. Ha a szervertől a válasz xml-ben jön akkor az Ajax.Request-et használjuk, ha viszont html-ben akkor az Ajax.Updater-t. Persze ha lehetőségünk van eleve html-t kapni a szervertől akkor miért ne tennénk ezt?
function adjUjKepet(){
var ptaKepHely = $("ptakep");
//ajax lekérés
//az updatert használjuk a request helyett mivel a válasz html-ben jön
var url = "kepvalaszt.php";
kepId = this.id ? 1 : 0;
var params = "id="+kepId;
Az adjUjKepet függvényünk indításként létrehozza a ptaKepHely változót, ebbe a html objektumba fogjuk majd beírni a szerver válaszát. Az url változóban adjuk meg a meghívandó szerver oldali programfile elérési útját. Mivel itt azonos könyvtárban van a jelenlegi oldalt kiszolgáló filelal, így csak a nevét kell megadni elérési út nélkül. Aztán – kizárólag az izgalom kedvéért – paramétereket is létrehozunk, hogy legyen mit átadni a kepvalaszt.phpnak.
Ezután jöhet az AJAX lekérés, amit végtelenül egyszerűvé tesz a prototype.
var ajax = new Ajax.Updater(
ptaKepHely,
url,
{
method: "get",
parameters: params,
onLoading: ptaLoading,
onException: ptaKepHelyHiba
}
);
}
Létrehozunk egy új Ajax.Updater objektumot. Az első paraméter ptaKepHely adja meg, hogy a szerver válaszát melyik html objektumban akarjuk megjelenítani, a második az url, hogy melyik szerver oldali alkalmazással kívánunk kommunikálni. A harmadik paraméterben megadjuk, hogy a lekérés get metódussal történjen, legyenek a php-nek átadva a paraméterek, és a következő 3 sorral pedig megmondjuk, hogy az egyes kommunikációs fázisokban mi történjen. Az onLoading esemény addig él amíg a szerver válaszára várunk, az onException pedig hiba esetén kel életre.
Az eseménykezelő függvények
Jó szokás szerint mindig tologatni szoktam, hogy a hibakezelést majd akkor ha…, és így általában el is marad. Szakítva ezzel a szép szokással most akkor kezdjük ezzel.
ptaKepHelyHiba
Hiba esetén egy rövid hibaüzenetet szeretnénk megjeleníteni és egy linket aminek a segítségével a felhasználók egyszerűen küldhetnek nekünk egy részletes bug reportot. Hiba akkor fordulhat elő, ha valami gond van a hálózati kommunikációval, rosszul adunk meg valami adatot, valaki letörli a meghívandó php fileunkat, stb. stb.
function ptaKepHelyHiba(ojjektum,hiba){
ojjektum.containers.failure.innerHTML = "Valami gubanc van. " + hiba.name + " :: " + hiba.fileName + " :: " + hiba.lineNumber + " :: " + hiba.message;
}
Ki is próbálhatjuk, úgy hogy mondjuk az url-t direkt hibásan adjuk meg. Ez a kis hibagyártás nem is volt olyan könnyen kikényszeríthető, mivel a wordpress kiszolgálja a nem létező fileokat is. Végül belepiszkáltam a függvénybe, és az url-ként egy html objektumot adtam meg. Na ez már hibát dob.
ptaLoading
Ha a szervertől a válasz lassan jön, mert hosszú a szerver oldal feldolgozási ideje, vagy lassú a hálózat, akkor gondoskodnunk kell róla, hogy a user valahogy lássa, hogy a program fut, a kommunikáció folyamatban van, de még nem érkezett meg a szerver válasza. Erre szolgál a ptaLoading függvény. Itt a töltés ideje alatt egy kis animált cuccot jelenítünk meg amiből a user rájöhet, hogy mi történik. Ilyen kis kütyüket innen lehet szerezni.
function ptaLoading(){
var ptaKepHely = $("ptakep");
ptaKepHely.innerHTML = "<img src=\"ajax-loader.gif\" alt=\"töltögetek\" />";
}
Ennek a függvénynek a segítségével így fog kinézni a boxunk a töltés alatt.
A szerver oldali script
Ennek magyarázatába nem akarok túlságosan belebonyolódni, mert nem sok kapcsolata van a témánkkal. A sleep azért kell, hogy láthassuk a loading állapotot. Mivel az updatert használtuk a szerver oldali scriptünknek html-t kell visszaadnia.
<?php sleep(2); //ezt éles alkalmazásokban nem javaslom$konyvtar = './images/'; $kiterjesztes = 'jpg'; $i = 0; $fajlok = array(); if ($dir = @opendir($konyvtar)) { while ($file = readdir($dir)) { if(preg_match("/[a-zA-Z0-9]*\.$kiterjesztes/",$file)) $fajlok[$i] .= $file; $i++; } closedir($dir); } else print 'Nem találok a szerveren megfelelő fileokat ;( '; print '<img src="'.$konyvtar.$fajlok[array_rand($fajlok)].'" width="100" />'; ?>
És akkor lássuk az alkotást:
Megjegyzések
- A <a href=”#” onclick=”return(false);” id=”amilinkunk”> típusú megoldások nem éppen a legelegánsabbak. De erről inkább máskor írok. Addig is : diszkrét javascript.
- Általában a felhasználók nem szeretik a technikai jellegű hibaüzeneteket, így nem is célszerű rájuk zúdítani. Barátságosabbá tehetjük az egész történetet, ha mondjuk csak annyit írunk ki, hogy sajnálom de elpusztultam és van melette egy link amire ha rákattint akkor egy részletes bug reportot kapunk emailben.
- Tesztelve: Firefox, Opera, Safari és IE. Mindenhol fut, az IE a képet összenyomja, de ezt itt én most nem fogom megoldani
- Forráskódok letölthetők innen (4 KB).
Ez a bejegyzés rrd billentyűzetéből potyogott ki 2007 április 21. napján 09:07:53-kor. Eddig 4,857 olvasást ért meg. A visszajelzéseket nyomonkövetheted ezzel az RSS feed-el. Véleményt nyilváníthatsz, vagy trackbackolhatsz a saját oldaladon.
JólMegMondjad!
9 vélemény
-
Sulik Szabolcs
2007 április 22. 07:09:51Hi
Túl sok mindent nem tudok hozzátenni

Talán annyit, hogy “elegánsabb”, ha a loading gif-et egyszerűen beteszed a html-be id=”loading” és style=”display:none”-nal (fontos!!!). Ezután onLoadingnál egyszerűen Element.show(‘loading’), majd betöltés után Element.hide(‘loading’).Prototype 1.4 leírás (magyar): http://prototype.rajmi.hu/prototype.js.hu.html
Prototype 1.5 leírás (angol): http://www.sergiopereira.com/articles/prototype.js.html
-
kicsiZ
2007 április 22. 23:27:58IE6.0 alatt ha rákattintok a linkre akkor müxik, ha megint rákattintok akkor felvillantja ugyanazt a képet és elkezd a végtelenségig forogni a letöltésjelző..
Ezért hanyagolom egyre inkább a prototype.js -t, csak a szívás van vele, hogy nem kezeli rendesen, hogy IE alatt status kód 200 jelenti a tranzakció végét FF alatt pedig 205.
u.i.
a muszájt sima j-vel írjuk
-
Wiktor
2007 április 23. 07:23:55Érdekes, hogy mennyire másképp álltam volna hozzá egy ilyen feladathoz, mind szerver oldalon, mind kliens oldalon.
Szerveroldalon tuti, csak egy glob-ot használtam volna, és nem egy egész html-t adtam volna vissza, hanem csak mondjuk a filenevét.
Kliens oldalon pedig dom-mal raktam volna be a képet a megfelelő helyre.
Persze értem én, hogy ez csak egy példa…
Mégis érdekes, hogy egy egyszerű feladatot is számtalan módon meg lehet oldani.
ui: a muszáj tényleg pontos j…
-
Pëkka
2007 április 23. 09:18:35Hát, én jól megmondom, hogy a muszáj az muszáj…
-
rrd
2007 április 23. 09:27:20Muszáj: kicsit be vagyok asszem lassulva. Hol kéne ezt javítanom?
-
Béla
2007 április 30. 06:11:49A JólMegMondjad!-nál muszáj lenne javítanod
-
rrd
2007 április 30. 06:34:43Béla: köszi, javítva.
-
Johnson
2008 január 3. 14:26:11kicsiZ felvetésével kapcsolatban mi a megoldás? Próbáltam 1.6-os Prototype-pal is és így sem működik IE alatt. Ez kicsit eltántorított a prototype-pal való ismerkedéstől. Sok ilyen hülyesége van a prototype-nak? Mennyire fogom szivatni magam, ha rállok a prototype alapú fejlesztésre?
-
rrd
2008 január 3. 15:58:48Johnson: kicsiZ által megtalált hiba nem a prototype-é hanem az enyém
Itt a leírásban próbáltam a lehető legegyszerűbbre venni a példát, hogy lehessen érteni. A prototype feltételezi, hogy a megoldandó feladat be van csomagolva egy objektumba, ami itt a példában nem történik. Ez okozza IE alatt a hibát.
Az ember utánna gyorsan megszokja, hogy a prototype mit vár el tőle és akkor sokat lehet nyerni a használatával.




