presentació ajax

16
Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware © Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/ Presentació d’Ajax La història d'AJAX està íntimament relacionada amb un objecte de programació anomenat XMLHttpRequest. L'origen d'aquest objecte es remunta a l'any 2000, amb productes com Exchange 2000, Internet Explorer 5 i Outlook Web Access. Tot va començar al 1998, quan Alex Hopmann i el seu equip es trobaven desenvolupant la llavors futura versió d’Exchange 2000. El punt feble del servidor de correu electrònic era el seu client via web, anomenat OWA (Outlook Web Access). Durant el desenvolupament de OWA, es van avaluar dues opcions: un client format només per pàgines HTML estàtiques que es recarregaven constantment i un client realitzat completament amb HTML dinàmic DHTML. Alex Hopmann va poder veure les dues opcions i es va decantar per la basada en DHTML. No obstant això, per ser realment útil aquesta última, li faltava un component essencial: quelcom que evités haver d'enviar contínuament els formularis amb dades al servidor. Motivat per les possibilitats futures de OWA, Alex va crear en un sol cap de setmana la primera versió del que va anomenar XMLHTTP. La primera demostració de les possibilitats de la nova tecnologia va ser un èxit, però faltava el més difícil: incloure aquesta tecnologia en el navegador Internet Explorer. Si el navegador no incloïa XMLHTTP de forma nativa, l'èxit del OWA s'hauria reduït enormement. El major problema és que faltaven poques setmanes perquè es llancés l'última beta d'Internet Explorer 5 prèvia al seu llançament final. Gràcies als seus contactes en l'empresa, Alex va aconseguir que la seva tecnologia s'inclogués en la llibreria MSXML que inclou Internet Explorer. De fet, el nom de l'objecte (XMLHTTP) es va triar per tenir una bona excusa que justifiqués la seva inclusió en la llibreria XML d'Internet Explorer, ja que aquest objecte està molt més relacionat amb HTTP que amb XML. Desenvolupar aplicacions AJAX requereix un coneixement avançat de totes i cadascuna de les tecnologies de programació. En les aplicacions web tradicionals, les accions de l'usuari a la pàgina (punxar en un botó, seleccionar un valor d'una llista, etc.) desencadenen cridades al servidor. Una vegada processada la petició de l'usuari, el servidor retorna una nova pàgina HTML al navegador de l'usuari. Aquesta tècnica tradicional per crear aplicacions web que funcioin correctament, però, no crea una bona sensació a l'usuari. En realitzar peticions contínues al servidor, l'usuari ha d'esperar al fet que es recarregui la pàgina amb els canvis sol·licitats. Si l'aplicació ha de realitzar peticions contínues, el seu ús es converteix en quelcom molest.

Upload: roger-casadejus-perez

Post on 26-Jan-2015

104 views

Category:

Documents


0 download

DESCRIPTION

Presentació d'Ajax. Més manuals a: http://www.exabyteinformatica.com

TRANSCRIPT

Page 1: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

Presentació d’Ajax

La història d'AJAX està íntimament relacionada amb un objecte de programació anomenat

XMLHttpRequest. L'origen d'aquest objecte es remunta a l'any 2000, amb productes com

Exchange 2000, Internet Explorer 5 i Outlook Web Access.

Tot va començar al 1998, quan Alex Hopmann i el seu equip es trobaven desenvolupant la

llavors futura versió d’Exchange 2000. El punt feble del servidor de correu electrònic era el seu

client via web, anomenat OWA (Outlook Web Access).

Durant el desenvolupament de OWA, es van avaluar dues opcions: un client format només per

pàgines HTML estàtiques que es recarregaven constantment i un client realitzat completament

amb HTML dinàmic DHTML. Alex Hopmann va poder veure les dues opcions i es va decantar

per la basada en DHTML. No obstant això, per ser realment útil aquesta última, li faltava un

component essencial: quelcom que evités haver d'enviar contínuament els formularis amb

dades al servidor.

Motivat per les possibilitats futures de OWA, Alex va crear en un sol cap de setmana la primera

versió del que va anomenar XMLHTTP. La primera demostració de les possibilitats de la nova

tecnologia va ser un èxit, però faltava el més difícil: incloure aquesta tecnologia en el

navegador Internet Explorer.

Si el navegador no incloïa XMLHTTP de forma nativa, l'èxit del OWA s'hauria reduït

enormement. El major problema és que faltaven poques setmanes perquè es llancés l'última

beta d'Internet Explorer 5 prèvia al seu llançament final. Gràcies als seus contactes en

l'empresa, Alex va aconseguir que la seva tecnologia s'inclogués en la llibreria MSXML que

inclou Internet Explorer.

De fet, el nom de l'objecte (XMLHTTP) es va triar per tenir una bona excusa que justifiqués la

seva inclusió en la llibreria XML d'Internet Explorer, ja que aquest objecte està molt més

relacionat amb HTTP que amb XML.

Desenvolupar aplicacions AJAX requereix un coneixement avançat de totes i cadascuna de les

tecnologies de programació.

En les aplicacions web tradicionals, les accions de l'usuari a la pàgina (punxar en un botó,

seleccionar un valor d'una llista, etc.) desencadenen cridades al servidor. Una vegada

processada la petició de l'usuari, el servidor retorna una nova pàgina HTML al navegador de

l'usuari.

Aquesta tècnica tradicional per crear aplicacions web que funcioin correctament, però, no crea

una bona sensació a l'usuari. En realitzar peticions contínues al servidor, l'usuari ha d'esperar

al fet que es recarregui la pàgina amb els canvis sol·licitats. Si l'aplicació ha de realitzar

peticions contínues, el seu ús es converteix en quelcom molest.

Page 2: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

Ajax permet millorar completament la interacció de l'usuari amb l'aplicació, evitant les

recarregues constants de la pàgina, ja que l'intercanvi d'informació amb el servidor es produeix

en un segon pla.

Les aplicacions construïdes amb Ajax eliminen la recarrega constant de pàgines mitjançant la

creació d'un element entremig de l'usuari i el servidor. La nova capa intermitja d'Ajax millora la

resposta de l'aplicació, ja que l'usuari mai es troba amb una finestra del navegador buida

esperant la resposta del servidor.

Les peticions HTTP al servidor es substitueixen per peticions Javascript que es realitzen a

l'element encarregat d'Ajax. Les peticions més simples no requereixen intervenció del servidor,

per la qual cosa la resposta és immediata. Si la interacció requereix una resposta del servidor,

la petició es realitza de forma asíncrona mitjançant Ajax. En aquest cas, la interacció de l'usuari

tampoc es veu interrompuda per recarregues de pàgina o llargues esperes per la resposta del

servidor.

Des de la seva aparició, s'han creat centenars d'aplicacions web basades en Ajax. En la majoria

de casos, Ajax pot substituir completament a altres tècniques com a Flash. A més, en el cas de

les aplicacions web més avançades, poden arribar a substituir a les aplicacions d'escriptori.

A continuació es mostra una llista d'algunes de les aplicacions més conegudes basades en Ajax:

· Gestors de correu electrònic: Gmail, Yahoo Mail i Windows Live Mail entre d’altres.

· Cartografia: Google Maps, Yahoo Maps i Windows Live Local entre d’altres.

· Aplicacions web i productivitat: Google Docs, Zimbra i Zoho entre d’altres.

Unes altres: Netvibes, Digg (notícies), Meebo (missatgeria), 30 Boxes (calendari), Flickr

(fotografia).

Anàlisis detallat

Una aplicació Ajax es compon de quatre grans blocs: instancia del objecte XMLHttpRequest,

preparar la funció de resposta, realitzar la petició al servidor i executar la funció de resposta.

Totes las aplicacions realitzades amb tècniques d’Ajax reben una instància en primer lloc del

objecte XMLHttpRequest, que és l’objecte clau que permet realitzar comunicacions amb el

servidor en segon pla, sense necessitat de recarregar les pàgines.

La implementació del objecte XMLHttpRequest depen de cada navegador, per tant és

necessari fer servir una discriminació senzilla en funció del navegador en el que se està

executant el codi:

if(window.XMLHttpRequest) { // Navegadors que segueixen els estàndars

peticio_http = new XMLHttpRequest();

}

Page 3: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

else if(window.ActiveXObject) { // Navegadors obsolets

peticio_http = new ActiveXObject("Microsoft.XMLHTTP");

}

Els navegadors que segueixen els estàndars (Firefox, Safari, Opera, Internet Explorer 7, 8, 9 i

10) implementen l’objecte XMLHttpRequest de forma nativa, pel que es pot obtenir a través

de l’objecte window. Els navegadores obsolets (Internet Explorer 6 i anteriors) implementen

l’objecte XMLHttpRequest com un objecte de tipus ActiveX.

Una vegada obtinguda l’instancia del objecte XMLHttpRequest, es prepara la funció que s’e

encarrega de processar la resposta del servidor. La propietat onreadystatechange del objecte

XMLHttpRequest permet indicar aquesta funció directament inserint el ssu codi mitjançant

una funció anònima o indicant una referència a una funció independent. En l’exemple anterior

s’indica directament el nom de la funció:

peticio_http.onreadystatechange = mostraContingut;

El codi anterior indica que quan l’aplicació rebi la resposta del servidor, s’ha d’executar la

funció mostraContingut(). Como és habitual, la referència a la funció s’indica mitjançant el seu

nom sense parèntesis, ja que d’una altra manera s’estaria executant la funció i

emmagatzemant el valor retornat en la propietat onreadystatechange.

Després de preparar l’aplicació per al retorn del servidor, es realitza la petició HTTP al

servidor:

peticio_http.open('GET', 'http://localhost/prova.txt', true);

peticio_http.send(null);

Les instruccions anteriors realitzen el tipus de petició més senzilla que es pot enviar al servidor.

En concret, es tracta d’una petició del tipus GET simple que no envia cap paràmetre al

servidor. La petició HTTP es crea mitjançant el mètode open(), en el que s’inclou el tipus de

petició GET, la URL sol·licitada (http://localhost/prova.txt)i un tercer paràmetre amb el valor

True.

Una vegada creada la petició HTTP, s’envia al servidor mitjançant el mètode send(). Aquest

mètode inclou un paràmetre que en l’exemple anterior té el valor Null.

Per últim, quan es rep la resposta del servidor, l’aplicació executa de forma automàtica la

funció establerta anteriorment.

function mostraContingut() {

if(peticio_http.readyState == 4) {

if(peticio_http.status == 200) {

Page 4: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

alert(peticio_http.responseText);

}

}

}

La funció mostraContingut() comprova en primer lloc que s'ha rebut la resposta del servidor

(mitjançant el valor de la propietat readyState). Si s'ha rebut esposta, es comprova que sigui

vàlida i correcta (comprovant si el codi d'estat HTTP retornat és igual a 200). Una vegada

realitzades les comprovacions, simplement es mostra per pantalla el contingut de la resposta

del servidor (en aquest cas, el contingut de l'arxiu sol·licitat) mitjançant la propietat

responseText.

Refactoritzant la primera aplicació

La primera aplicació AJAX mostrada anteriorment presenta algunes mancances importants. A

continuació, es refactoritza el seu codi ampliant-ho i millorant-ho perquè s'adapti millor a

altres situacions. En primer lloc, es defineixen unes variables que s'utilitzen en la funció que

processa la resposta del servidor:

var READY_STATE_UNINITIALIZED = 0;

var READY_STATE_LOADING = 1;

var READY_STATE_LOADED = 2;

var READY_STATE_INTERACTIVE = 3;

var READY_STATE_COMPLETE = 4;

Com es veurà més endavant, la resposta del servidor només pot correspondre a algun dels cinc

estats definits per les variables anteriors. D'aquesta forma, el codi pot utilitzar el nom de cada

estat en comptes del seu valor numèric, per la qual cosa es facilita la lectura i el manteniment

de les aplicacions.

A més a més, la variable que emmagatzema la instància de l'objecte XMLHttpRequest es

transforma en una variable global, de manera que totes les funcios que fan ús d'aquest objecte

tinguin un accés directe sobre el mateix:

var peticio_http;

A continuació, es crea una funció genèrica de carga de continguts mitjançant Ajax:

Page 5: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

function cargaContenido(url, metode, funcio) {

peticio_http = inicialitza_xhr();

if(peticio_http) {

peticio_http.onreadystatechange = funcio;

peticio_http.open(metode, url, true);

peticio_http.send(null);

}

}

La funció definida admet tres paràmetres: la URL del contingut que es va a carregar, el mètode

utilitzat per realitzar la petició HTTP i una referència a la funció que processa la resposta del

servidor.

En primer lloc, la funció carregaContingut() inicialitza l'objecte XMLHttpRequest (anomenat xhr

de forma abreujada). Una vegada inicialitzat, s'empra l'objecte peticio_http per establir la

funció que processa la resposta del servidor. Finalment, la funció carregaContingut() realitza la

petició al servidor emprant la URL i el mètode HTTP indicats com a paràmetres.

La funció inicialitza_xhr() s'empra per encapsular la creació de l'objecte XMLHttpRequest:

function inicialitza_xhr() {

if(window.XMLHttpRequest) {

return new XMLHttpRequest();

}

else if(window.ActiveXObject) {

return new ActiveXObject("Microsoft.XMLHTTP");

}

}

La funció mostraContingut() també se refactoritza per a emprar les variables globals definides:

function mostraContingut() {

Page 6: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

if(peticio_http.readyState == READY_STATE_COMPLETE) {

if(peticio_http.status == 200) {

alert(peticio_http.responseText);

}

}

}

Per últim, la funció descarregaArxiu() simplement realitza una crida a la funció

carregaContingut() amb els paràmetres adequats:

function descarregaArxiu() {

carregaContingut("http://localhost/prova2.txt", "GET", mostraContingut);

}

A continuació es mostra el codi complet de la refactorització de la primera aplicació:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>

<head>

<title>Prova desde Ajax</title>

<script type="text/javascript" language="javascript">

var READY_STATE_UNINITIALIZED=0;

var READY_STATE_LOADING=1;

var READY_STATE_LOADED=2;

var READY_STATE_INTERACTIVE=3;

Page 7: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

var READY_STATE_COMPLETE=4;

var peticio_http;

function carregaContingut(url, metode, funcio) {

peticio_http = inicialitza_xhr();

if(peticio_http) {

peticio_http.onreadystatechange = funcio;

peticio_http.open(metode, url, true);

peticio_http.send(null);

}

}

function inicialitza_xhr() {

if(window.XMLHttpRequest) {

return new XMLHttpRequest();

}

else if(window.ActiveXObject) {

return new ActiveXObject("Microsoft.XMLHTTP");

}

}

function mostraContingut() {

if(peticio_http.readyState == READY_STATE_COMPLETE) {

if(peticio_http.status == 200) {

alert(peticio_http.responseText);

Page 8: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

}

}

}

function descarregaArxiu() {

carregaContingut("http://localhost/prova2.txt", "GET", mostraContingut);

}

window.onload = descarregaArxiu;

</script>

</head>

<body></body>

</html>

Utilitats i objectes per a Ajax

Una de les operacions més habituals en les aplicacions Ajax és la d'obtenir el contingut d'un

arxiu o recurs del servidor. Per tant, construirem un objecte que permeti realitzar la càrrega de

dades del servidor simplement indicant el recurs sol·licitat i la funció encarregada de processar

la resposta:

var carregador = new net.CarregadorContingutss("pagina.html", processaResposta);

La lògica comuna d'Ajax s'encapsula en un objecte de manera que sigui fàcilment reutilitzable.

Aplicant els conceptes d'objectes de Javascript, funcios constructores i l'ús de prototype, és

possible realitzar de forma senzilla l'objecte carregador de continguts:

var net = new Object();

net.READY_STATE_UNINITIALIZED=0;

net.READY_STATE_LOADING=1;

Page 9: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

net.READY_STATE_LOADED=2;

net.READY_STATE_INTERACTIVE=3;

net.READY_STATE_COMPLETE=4;

// Constructor

net.CarregadorContinguts = function(url, funcio, funcioError) {

this.url = url;

this.req = null;

this.onload = funcio;

this.onerror = (funcioError) ? funcioError : this.defaultError;

this.carregaContingutXML(url);

}

net.CarregadorContinguts.prototype = {

carregaContingutXML: function(url) {

if(window.XMLHttpRequest) {

this.req = new XMLHttpRequest();

}

else if(window.ActiveXObject) {

this.req = new ActiveXObject("Microsoft.XMLHTTP");

}

if(this.req) {

try {

var loader = this;

this.req.onreadystatechange = function() {

loader.onReadyState.call(loader);

Page 10: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

}

this.req.open('GET', url, true);

this.req.send(null);

} catch(err) {

this.onerror.call(this);

}

}

},

onReadyState: function() {

var req = this.req;

var ready = req.readyState;

if(ready == net.READY_STATE_COMPLETE) {

var httpStatus = req.status;

if(httpStatus == 200 || httpStatus == 0) {

this.onload.call(this);

}

else {

this.onerror.call(this);

}

}

},

defaultError: function() {

alert("S’ha produït un error l’obtenir les dades"

+ "\n\nreadyState:" + this.req.readyState

+ "\nstatus: " + this.req.status

Page 11: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

+ "\nheaders: " + this.req.getAllResponseHeaders());

}

}

Una vegada definit l’objecte net amb el seu mètode CarregadorContinguts(), ja és possible

utilitzar-ho en las funcioes que s’encarreguen de mostrar el contingut de l’arxiu del servidor:

function mostraContingut() {

alert(this.req.responseText);

}

function carregaContinguts() {

var cargador = new net.CarregadorContinguts("http://localhost/prova2.txt",

mostraContingut);

}

window.onload = carregaContinguts;

En l’exemple anterior, l’aplicació mostra un missatge amb els continguts de la URL indicada:

Missatge mostrat quan el resultat és exitós.

Missatge mostrat quan el resultat és reeixit

D'altra banda, si la URL que es vol carregar no és vàlida o el servidor no respon, l'aplicació

mostra el següent missatge d'error:

Missatge mostrat quan el resultat és erroni.

Missatge mostrat quan el resultat és erroni

El codi del carregador de continguts fa un ús intensiu d'objectes, JSON, funcios anònimes i ús

de l'objecte this. Seguidament, es detalla el funcioament de cadascuna de les seves parts.

Page 12: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

El primer element important del codi font és la definició de l'objecte net.

var net = new Object();

Es tracta d'una variable global que encapsula totes les propietats i mètodes relatius a les

operacions relacionades amb les comunicacions per xarxa. En certa manera, aquesta variable

global simula el funcioament dels namespaces ja que evita la col·lisió entre noms de propietats

i mètodes diferents.

Després de definir les constants emprades per l'objecte XMLHttpRequest, es defineix el

constructor de l'objecte CarregadorContinguts:

net.CarregadorContinguts = function(url, funcio, funcioError) {

this.url = url;

this.req = null;

this.onload = funcio;

this.onerror = (funcioError) ? funcioError : this.defaultError;

this.carregaContingutXML(url);

}

Encara que el constructor defineix tres paràmetres diferents, en realitat només els dos primers

són obligatoris. D'aquesta forma, s'inicialitza el valor d'algunes variables de l'objecte, es

comprova si s'ha definit la funció que s'empra en cas d'error (si no s'ha definit, s'empra una

funció genèrica definida més endavant) i s'invoca el mètode responsable de carregar el recurs

sol·licitat (carregaContingutXML).

net.CarregadorContinguts.prototype = {

carregaContingutXML:function(url) {

...

},

onReadyState:function() {

...

},

defaultError:function() {

...

}

}

Page 13: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

Els mètodes emprats per l'objecte net.carregaContinguts es defineixen mitjançant el seu

prototip. En aquest cas, es defineixen tres mètodes diferents: carregaContingutXML() per

carregar recursos de servidor, onReadyState() que és la funció que s'invoca quan es rep la

resposta del servidor i defaultError() que és la funció que s'empra quan no s'ha definit de

forma explícita una funció responsable de gestionar els possibles errors que es produeixin en

la petició HTTP.

La funció defaultError() mostra un missatge d'avís de l'error produït i a més mostra el valor

d'algunes de les propietats de la petició HTTP:

defaultError:function() {

alert("S’ha produït un error al obtenir les dades"

+ "\n\nreadyState:" + this.req.readyState

+ "\nstatus: " + this.req.status

+ "\nheaders: " + this.req.getAllResponseHeaders());

}

En aquest cas, l’objecte this es resol a l’objecte net.carregaContinguts, ja que és l’objecte que

conté la funció anònima que s’està executant.

D’altra banda, la funció onReadyState és l’encarregada de gestionar la resposta del servidor:

onReadyState: function() {

var req = this.req;

var ready = req.readyState;

if(ready == net.READY_STATE_COMPLETE) {

var httpStatus = req.status;

if(httpStatus == 200 || httpStatus == 0) {

this.onload.call(this);

} else {

this.onerror.call(this);

}

Page 14: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

}

}

Després de comprovar que la resposta del servidor està disponible i és correcta, es realitza la

crida a la funció que realment processa la resposta del servidor d'acord a les necessitats de

l'aplicació.

this.onload.call(this);

L'objecte this es resol com net.CarregadorContinguts, ja que és l'objecte que conté la funció

que s'està executant. Per tant, this.onload és la referència a la funció que s'ha definit com a

responsable de processar la resposta del servidor (es tracta d'una referència a una funció

externa).

Normalment, la funció externa encarregada de processar la resposta del servidor, requerirà

accedir a l'objecte XMLHttpRequest que emmagatzema la petició realitzada al servidor. En un

altre cas, la funció externa no serà capaç d'accedir al contingut retornat pel servidor.

Com ja hem vist anteriorment, el mètode call() és un dels mètodes definits per a l'objecte

Function(), i per tant disponible per totes les funcions de Javascript. Emprant el mètode call()

és possible obligar a una funció a ser executada sobre un objecte concret. En altres paraules,

emprant el mètode call() sobre una funció, és possible que dins d'aquesta funció l'objecte this

es resolgui com l'objecte passat com a paràmetre en el mètode call().

Així, la instrucció this.onload.call(this); s'interpreta de la següent forma:

L'objecte this que es passa com a paràmetre de call() es resol com l'objecte

net.CarregadorContinguts.

L'objecte this.onload emmagatzema una referència a la funció externa que es va a emprar per

processar la resposta.

El mètode this.onload.call() executa la funció, la referència de la qual, s'emmagatzema en

this.onload.

La instrucció this.onload.call(this); permet executar la funció externa amb l'objecte

net.CarregadorContinguts accessible a l'interior de la funció mitjançant l'objecte this.

Finalment, el mètode carregaContingutXML s'encarrega d'enviar la petició HTTP i realitzar la

trucada a la funció que processa la resposta:

carregaContingutXML:function(url) {

if(window.XMLHttpRequest) {

this.req = new XMLHttpRequest();

}

else if(window.ActiveXObject) {

Page 15: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

this.req = new ActiveXObject("Microsoft.XMLHTTP");

}

if(this.req) {

try {

var loader=this;

this.req.onreadystatechange = function() {

loader.onReadyState.call(loader);

}

this.req.open('GET', url, true);

this.req.send(null);

} catch(err) {

this.onerror.call(this);

}

}

}

En primer lloc, s'obté una instància de l'objecte XMLHttpRequest en funció del tipus de

navegador. Si s'ha obtingut correctament la instància, s'executen les instruccions més

importants del mètode carregaContingutXML:

var loader = this;

this.req.onreadystatechange = function() {

loader.onReadyState.call(loader);

}

this.req.open('GET', url, true);

this.req.send(null);

A continuació, s'emmagatzema la instància de l'objecte actual (this) en la nova variable loader.

Una vegada emmagatzemada la instància de l'objecte net.CarregadorContinguts, es defineix la

funció encarregada de processar la resposta del servidor. En la següent funció anònima:

Page 16: Presentació Ajax

Más manuales en: http://www.exabyteinformatica.com/manuales-y-apuntes-freeware

© Roger Casadejús Pérez | http://www.exabyteinformatica.com/tienda/

this.req.onreadystatechange = function() { ... }

A l'interior d'aquesta funció, l'objecte this no es resol en l'objecte net.CarregadorContinguts,

per la qual cosa no es pot emprar la següent instrucció:

this.req.onreadystatechange = function() {

this.onReadyState.call(loader);

}

No obstant això, des de l'interior d'aquesta funció anònima si és possible accedir a les variables

definides en la funció exterior que l'engloba. Així, des de l'interior de la funció anònima sí que

és possible accedir a la instància de l'objecte net.CarregadorContinguts que es va

emmagatzemar anteriorment.

En el codi anterior, no és obligatori emprar la crida al mètode call(). Es podria haver definit de

la següent forma:

var loader=this;

this.req.onreadystatechange = function() {

// loader.onReadyState.call(loader);

loader.onReadyState();

}

A l'interior de la funció onReadyState, l'objecte this es resol com net.ContentLoader, ja que es

tracta d'un mètode definit en el prototip del propi objecte.