Een paar dagen geleden schreef Erik-Jan al een artikel over Ajax voor beginners. Hierin werden de principes van Ajax (Asynchronous JavaScript And XML) uitgelegd en werd een eenvoudig voorbeeld gegeven om er lekker mee aan de slag te kunnen. In het kort komt het er op neer dat je JavaScript kunt gebruiken om een server side script (bijv. php of asp) aan te roepen, waardoor je zonder de pagina te herladen data uit bijvoorbeeld een database kunt ophalen.
Dit artikel is hier een vervolg op. We gebruiken hier een uitgebreidere XML parser en leggen uit waarom dit zo is. In het kort komt de uitbreiding hier op neer:
Zoals ik al zei in punt 1 was het verschil tussen deze XML parser en die uit het eerste artikel dat deze object georiënteerd gebouwd is. Klinkt mooi, maar waarom dan?
Wat je ziet bij de vorige XML parser is dat het xmlHttpRequest in een globale variabele gestopt werd. Dat werkt op zich prima, totdat je meerdere requests tegelijk wilt uitvoeren. Dat is immers (ook) de kracht van Ajax ook, de ‘a’ van asynchronous. Wanneer gaat het dan fout?
Stel je hebt een request uitgevoerd en de behandeling van dit request duurt 2 seconden. Nu wil je binnen die 2 seconden nog een volgend request uitvoeren. Dan zal je hiervoor weer de globale variabele moeten gebruiken. Maar het gaat fout zodra het tweede request met de verwerking bezig is en het eerste ‘terugkomt’ (readystate == 4). Dan is namelijk het eerste request overschreven door het tweede en ben je dus je data kwijt. Onhandig dus. Nu kun je wel twintig verschillende globale variabelen aan gaan maken, maar dat lijkt me ook niet echt de bedoeling.
De oplossing? Maak de parser object georiënteerd. Elk request krijgt zijn eigen object, waardoor er geen data meer door elkaar gaat lopen en verloren gaat. Ik ga hier niet vertellen hoe het hele object georiënteerd programmeren an sich werkt, maar ga er maar vanuit dat het werkt ;-). Als je echt graag wilt weten hoe het werkt, dan spit je of de code door, of je zoekt een mooi artikel over object georiënteerd programmeren in JavaScript. Zo, daar kom ik even makkelijk van af. :-)
Er was nog een tweede reden waarom ik over deze nieuwe XML parser begon. Juist, de XML zelf. Het server side script dat je aanroept zal in plaats van data (opgemaakt door HTML) naar het scherm spugen een mooi XML document genereren. Deze XML halen we vervolgens met JavaScript op en we kunnen ermee doen wat we willen.
Genoeg gebazeld, nu de code maar eens even. Omdat het iets te lang wordt om in dit artikel te plaatsen moet je hem maar even downloaden. De code zal ik niet regel voor regel uitspitten, maar ik zal even de belangrijkste functies aan bod laten komen.
In regel 9 t/m 16 worden een aantal variabelen gedeclareerd die we later nodig hebben. Vervolgens wordt de init() functie aangeroepen. Deze functie wordt meteen uitgevoerd zodra je het object aanmaakt. Hierin zou je bijvoorbeeld een ‘loading’ plaatje kunnen laten tonen. Aan het eind van het verhaal, als het request klaar is wordt de _closeLoading functie aangeroepen waarmee je dit ‘loading’ plaatje weer kunt laten verdwijnen.
Vervolgens hebben we een aantal functies die de instellingen van het huidige object bepalen. Ik zal ze even kort langslopen:
setResponseAsText(): je kan ervoor kiezen om in plaats van XML ook gewoon text als data terug te krijgen. In dat geval moet je deze functie aanroepen.setDisabledASync(): normaal gesproken wil je graag asynchrone requests uitvoeren. Dat wil zeggen dat het ene request niet op het andere hoeft te wachten en je dus lekker snel kunt werken. Mocht je dat niet willen, dan kun je dit dus uitzetten.setFunction(): aan de setFunction() functie kun je (komma gescheiden) een set van functies meegeven die moeten worden uitgevoerd, nadat het request klaar is. Hierin kun je dus functies zetten die de XML verwerken en de data in HTML naar het scherm spugen.setURL(url): hiermee geef je de URL mee van het server side script wat moet worden aangeroepen.addParam(param, value): met deze functie stel je de parameters in voor de URL die je aanroept. Dus in plaats van achter de URL (na het vraagteken) alle parameters te plakken (dat mag wel, maar hoeft dus niet), kun je deze functie zo vaak aanroepen als je wilt om al je parameters mee te geven. Wel zo overzichtelijk.Een voorbeeld van het aanmaken van zo.n object kan er als volgt uitzien:
function getZoekresultaten(zoekwoorden, boek) {
var xmlhttp = new HTTPDataConnection();
xmlhttp.setURL("resultaten.php");
xmlhttp.addParam("zoekwoorden", zoekwoorden.value);
xmlhttp.addParam("boek", boek.value);
xmlhttp.setFunction(verwerkInput);
xmlhttp.requestData();
}
Dan de belangrijkste functie: requestData(). In deze functie wordt het daadwerkelijke request uitgevoerd. Bovenin de functie worden nog even de ingestelde parameters achter de URL geplakt en vervolgens wordt het xmlHTTPRequest geopend en wordt de boel in werking gezet. Aan het eind wordt de handleData() functie aangeroepen waar de data wordt verwerkt.
De handleData() functie haalt de data op nadat het request klaar is. Dit weet je doordat de readystate variabele de waarde ’4′ heeft. De (XML) data die we terugkrijgen van het server side script wordt in de this.receive variabele gestopt.
Een voorbeeld van een XML document vindt je hieronder:
Vervolgens worden in de handleData() functie de door jou opgegeven functies (via de setFunction() functie) aangeroepen. Tot slot krijgt de _closeLoading() functie een schop waarmee je eventuele loading plaatjes weer weg kunt stoppen.
Wil je data die je in je XML terug hebt gekregen op je scherm tonen, dan kan dat in een van de functies die je aanroept na het request. In onderstaand voorbeeld heet deze functie verwerkInput(). Het commentaar zegt genoeg denk/hoop ik.
function verwerkInput(xmlhttp) {
// haal data op als array, met XML element 'object' als parent
var dataArray = xmlhttp.getDataAsArray("object");
// haal aantal resultaten op uit XML element 'count'.
var count = xmlhttp.getDataValue("count");
if(count != 0) {
if(count > 25) {
output ="
Er zijn meer dan 25 resultaten gevonden. Verfijn uw zoekopdracht.
n";
}
else {
output ="
Er zijn " + count + " resultaten gevonden.
n";
}
output += "
| " + boek + " " + hoofdstuk + ":" + vers + " | " + tekst + " |
n";
document.getElementById('output').innerHTML = output;
}
}
Tot zover deze object georiënteerde XML parser. Ik hoop dat je het een beetje hebt kunnen volgen. Zo niet, schroom dan vooral niet om in het forum een vraag te stellen.
Zijn we dan nu klaar met Ajax? Nee, nog niet helemaal. Binnenkort komt er nog een toepassing van dit artikel. In deze toepassing gaan we een zoekmachine maken die m.b.v. Ajax de data ophaalt en weergeeft.
Noot: Dit artikel werd u mede mogelijk gemaakt door Ronald Everts.