In het recente verleden heb ik met gemende gevoelens te maken gehad met
JavaScript. Ook heb ik hierbij Ajax moeten toepassen in websites. Ik vind het
gewoon plakband voor websites.
Waarom?
Websites gedragen zich fundamenteel anders dan ‘klassieke’ WinForm
applicaties en ook gedragen zij zich anders dan de moderne WPF variant. Websites zijn gebaseerd op technieken van pakweg tien-twintig jaar terug waarin browsers nog in de kinderschoenen stonden, bandbreedte en servercapaciteit schaars was en browsers ronduit dom waren.
Daartegenover staat dat gebruikers van bv. administratieve systemen rijke
interfaces met veel interactie gewend zijn. Het grootste deel van de huidige
generatie gebruikers is opgegroeid in de hoogtijdagen van het client/server
tijdperk en wat hun betreft was dat een heel aardige werkomgeving. Dat
tegenwoordig de meeste applicaties juist als webapplicatie gebouwd wordt, is
vaak ingegeven door enigzins gedateerde ideeën over de vereenvoudigde uitrol
(nooit eens naar Click-Once gekeken?), de ‘denkbeeldige’ eenvoud van het ontwerp door de gelaagdheid en het feit dat de hele wereld er achteraan rent dus het zal wel goed zijn. Dat de ontwikkeling vaak veel lastiger is dan een WinForm
applicatie, omdat voortdurend tussen alle losse lagen met data geschoven moet
worden en dat de ontwikkeltijd meestal langer is, daar wordt gewoon aan voorbij
gegaan.
Nu is een website bouwen op zich niet lastig. Met een gemiddelde
ontwikkelomgeving wordt het tegenwoordig redelijk triviaal om dmv. een MVC
(Model View Controller) of zelfs een MVP (Model View Presenter) patroon een
applicatie in elkaar te zetten. Dit gecombineerd met technologie zoals WCF maakt betrouwbare datauitwisseling steeds eenvoudiger.
Het grootste probleem is juist dat deze glimmende webapplicatie zich moeten
gedragen als de eerste de beste client/server WinForm applicatie. Veel
webapplicatie zijn vervangingen van bestaande WinForm applicaties waarbij de
nodige uitbreidingen met Client/Server in het achterhoofd zijn uitgedacht. Want
het tweede probleem is dat veel webapplicaties ontworpen worden met de vereisten van een Client/server applicatie. De technologie is met sprongen vooruit gegaan, de ontwerpers zitten nog met hun hoofd en ideeën in de jaren tachtig/negentig van de vorige eeuw.
Dit betekent dat ondanks de zegeningen van multi-tier gelaagdheid,
server-side pagina opbouw van pagina’s en de aanwezigheid van prachtige
services, de frontend (de browser dus) nog steeds grote hoeveelheden dat moet
blijven tonen op het scherm. En hierbij moet de volledige GUI in sync gehouden
worden, afhankelijk van de interactie door de gebruiker. We zitten dus met
enorme lijsten in tabellen, het enabelen en disabelen van knoppen en een
dynamische toegang tot data (Iedere interactie van de gebruiker moet hele
schermen op hun kop zetten). En er is ook nog de vereiste dat de data per
direct voor de gebruiker beschikbaar moet zijn. De round-trip naar de server
moet daarbij nihil zijn terwijl de duur daarvan juist een direct gevolg is van
die uitbundige gui.
In plaats van het opvoeden van de klant (lees: de ontwerper) hebben we dus
ons heil gezocht is plakband om website pagina’s er als een winform uit te laten
zien. Natuurlijk hebben wij ontwikkelaars hier zelf ook een hand in gehad. We
willen pleasen dus zeggen geen nee en het is natuurlijk fraai om asynchroon data
op te halen compleet met animated gifs om de gebruiker af te leiden totdat de
aanroep afgewerkt is.
Genoeg gebashed… Dus u wilt Ajax? Dan krijgt u Ajax.
In het verleden heb ik nog gebruik gemaakt van Ajax Pro
(http://www.ajaxpro.info/). Voldeed prima aan de verwachtingen en was redelijk eenvoudig op te nemen in het webproject. Met het eenvoudig in javascript aanroepen van een asp.net methode op een aspx pagina kon serverside data verzameld en opgehaald worden. Ook hebben we toen nog naar Anthem.Net gekeken.
Deze had een hele set van aardige webcontrols welke Ajax enabled waren. Asp.Net AJAX van MS viel helaas af want we zaten toen nog in VS2003.
Maar met de komst van het Ajax updatepanel, de Ajax extensions en zelfs de
Ajax controls is Ajax veel toegankelijker geworden. Dit is nu helemaal triviaal
met VS2008 waar het standaard in opgenomen is. We kunnen nu dus helemaal los om er een zooi op de client van te maken 🙂 Download dus snel de extra
toolkit .
Toch is er voor de liefhebber van eenvoudig lichtgewicht Ajax gebruik vanuit
JavaScript een tussenoplossing en die wordt hieronder getoond in acht eenvoudige stappen:
Stap 1
Open Visual Studio 2008 en start een nieuw webproject.
Stap 2
Voeg een ScriptManager (op tabblad AJAX Extensions van de Toolbox) toe binnen de HTML Form op de Default.Aspx:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"></asp:ScriptManager>
Stap 3
EnablePageMethods moet dus aangezet worden. In VS2008 is dit voldoende, Extra HttpHandlers of web.config aanpassingen zijn niet meer nodig zoals vroeger… de web.config is al aardig voorbereid.
Stap 4
Op de server side webpagina _Default.aspx plaats je een static webmethod:
[WebMethod] public static string[] GeefLijst(int lengte) { string[] lijst = new string[lengte]; for (int i = 0; i < lengte; i++) { lijst[i] = i.ToString(); } return lijst; }
Dit geeft eenvoudig een array van strings terug.
En zet alvast ter illustratie een breakpoint in de WebMethod.
Stap 5
Deze WebMethod roep je aan in een JavaScript functie (bv. geplaatst in de
HTML Head)
<script type="text/javascript"> function voerPageMethodUit() { alert('voerPageMethodUit'); PageMethods.GeefLijst(5, geefLijstResult); } ... </script>
Zie dat de methode GeefLijst voorafgegaan wordt door de ‘namespace’
PageMethods en niet _Default. Ook consumeren we (nog) niet de geretourneerde waarde van de WebMethod. Let er ook op dat de JavaScript functies met een kleine letter beginnen, in tegenstelling tot de WebMethod.
Stap 6
De aanroep is asynchroon (het is tenslotte Ajax) dus je moet bij de
terugkomst van de serveraanroep de response verwerken. Hiervoor is een extra
methode aanwezig welke bij de aanroep bekend is gemaakt:
function geefLijstResult(result) { alert('Server gaf resultaat: ' + result); }
Een naamconventie is nu wel handig om de twee methodes aan elkaar te
koppelen: …Result geeft hier aan dat het een asynchrone response methode is
van de call-back.
Stap 7
Alles staat nu klaar voor aan aanroep, nu komt alleen nog het toepassen. Roep
dus de JavaScript functie aan, bv. in het onload event van de HTML body.
<body onload=" voerPageMethodUit()" >
Stap 8
Start nu de website (bij voorkeur met de optie tot debuggen aangezet). Als
alles klopt wacht nu de pagina na het opstarten direct op de eerst alert. Daarna
komen we in de breakpoint in de WebMethod op de server en als laatste wordt de inhoud van de array getoond door de alert in de response method.
Tadaah, een Ajax callback in JavaScript is echt eenvoudig geworden via de
ScriptManager. Kijk voor meer details op: http://msdn.microsoft.com/en-us/library/bb398995.aspx