Daily Archives: 2007.03.21. 22:00

Hibakeresés és nyomkövetés JavaScriptben

Szerver oldali programozók számára a JavaScript írásnál csak egy rémisztőbb és utálatosabb dolog létezik: JavaScriptet debuggolni. Márpedig ha elkezdjük használni a Microsoft AJAX Library-t akár önállóan, akár az ASP.NET AJAX részeként, előbb utóbb erre is szükségünk lesz.

Debug környezet kialakítása

Ahhoz, hogy minden kézre álljon, először az Internet Explorert kell beizgatnunk a hibakeresére, irány tehát a Tools – Internet Options – Advanced fül és ott:

  • Disable script debugging (Internet Explorer): off
  • Disable script debugging (Other): off
  • Display a notification about every script error: on
  • Show friendly HTTP error messages: off

Ha szerver oldali kóddal együtt használjuk az AJAX Library-t, akkor állítsuk be web.config-ban a debug="true" kapcsolót, így a kliens oldali szkriptek debug változatával fog futni az oldalunk, ami segíthet a hibakeresésben.

De nincs feltétlenül szükségünk az ASP.NET-re, lehet debuggolni egyszerű HTML oldalba ágyazott szkriptet is. Ebben az esetben is érdemes lehet Visual Studioban létrehozni egy webes projektet, már csak azért is, mert:

  • Megkapjuk a Studio szokásos kód szerkesztési szolgáltatásait.
  • Könnyebb lesz a böngészőt és a Studio debuggerét összekapcsolni.
  • Használhatjuk a Studio részeként elérhető developer web servert.
Debug

A Microsoft AJAX Library hibakeresési szolgáltatásait a Sys.Debug osztály fogja össze. Ha bárhol a forráskódban meghívjuk a fail metódust, a böngésző meg fogja kérdezni, hogy akarunk-e debuggolni, és ha igen, akkor rögtön rá tud csatlakozni a VS-ben megnyitott webes projektünkre. Ennyi a forráskódban:

    Sys.Debug.fail( "Irány a debugger!" );

Ennyi a böngészőben:

A Yes-re kattintva az élmény ismerős lesz, csak tegyünk F9-cel egy breakpointot a következő szkript sorra és máris mehetünk végig soronként az F10-et csapkodva. Ha az AJAX Library szkriptek debug változatait linkeljük be az oldalunkra, akkor F11-gyel is érdemes lehet ugrálni, megnézhetjük, mit hogyan implementált a Nagy Testvér! Ki lehet például deríteni, hogy a fail a böngésző debugger utasítását használja, amennyiben azt a böngésző támogatja.

Működik a Watch és a Locals ablak is, csak éppen nem túl érdekesek, hiszen property-kre vannak kihegyezve, amit sajnos itt többnyire metódusok helyettesítenek (például a TextBox osztálynak get_text() és set_text(..) metódusai vannak). Jól használható viszont az Immediate ablak, ahol közvetlenül hívhatunk meg függvényeket vagy kérdezhetjük le változók értékeit.

Trace

Ha a VS debug módban van, a trace metódus hívásával írhatunk az Output ablakba. Ha pedig szeretnénk formázni a kiírandó szöveget, akkor örülhetünk, hogy az AJAX Library-ben is van String.format metódus:

    Sys.Debug.trace( "Szia Világ!" );
    var txtName = new Sys.Preview.UI.TextBox( $get( "txtName" ) );
    Sys.Debug.trace( String.format( "txtName.text = '{0}'", txtName.get_text() ) );

Ha ugyanezt a szöveget a böngészőben is meg szeretnénk jeleníteni, akkor tegyünk egy TraceConsole id-val ellátott TEXTAREA tag-et az oldalra és ott is meg fog jelenni:

    <textarea id='TraceConsole' rows="30" cols="70"></textarea>

Ha bonyolultabb objektumokat szeretnénk trace-elni, akkor élvezhetjük a traceDump metódus szolgáltatásait, ami megpróbál a lehető legtöbbet kiírni az objektumról. Második paraméterként megadhatunk egy sztringet, ami segít eligazodni a trace üzenetek között:

    Sys.Debug.traceDump( txtName, "Szövegdoboz" );

Az én esetemben egy textboxról (<input id="txtName" type="text" value="MSDN Kompetencia Központ" />) ennyit tudott:

    Szövegdoboz {Sys.Preview.UI.TextBox}
            validated: null
            _updating: false
            _initialized: false
            _idSet: false
            _id: null
            _visibilityMode: 0
            _parent: null
            _validationMessage: null
            _validated: false
            _invalid: false
            _validators: null
            _valuePropertyName: null
            _keyPressHandler: null
            _changeHandler: null
            _text: null
            _element {INPUT - txtName}
            _oldDisplayMode: 

Ebben az a szomorú, hogy a text tulajdonságnak igenis volt értéke, ami nem más, mint a value attribútum értéke, amit ez itt nem tudott megjeleníteni, szóval csak óvatosan! smile_sad 

Ugyanez használható egyedi objektumokra:

    var person = { firstName: "György", lastName: "Balássy", year: 2007 };
    Sys.Debug.traceDump( person, "Én" );
    Én {Object}
            firstName: György
            lastName: Balássy
            year: 2007

És használható kivételek adatainak megjelenítésére is:

    try
    {            
        throw Error.notImplemented( "Ez még nincs kész." );
    }
    catch( ex )
    {
        Sys.Debug.traceDump( ex );
    }

Ebben pedig az az érdekes, hogy a Firefox többet árul el egy kivételről, mint az IE, az utóbbiban ugyanis nincs stack trace, de a Firefoxban van, sőt ott van fileName és lineNumber is:

    traceDump {Error}
            message: Sys.NotImplementedException: Ez még nincs kész.
            name: Sys.NotImplementedException
            stack: pageLoad([object Object],[object Object])@http://localhost:1531/PureClientAjax/Samples/DebugTrace.htm:41
    Sys$_Application$raiseLoad()@http://localhost:1531/PureClientAjax/Scripts/AjaxLibrary/MicrosoftAjax.debug.js:3758
    Sys$_Application$_doInitialize(240)@http://localhost:1531/PureClientAjax/Scripts/AjaxLibrary/MicrosoftAjax.debug.js:3795
    apply([object Object],[object Object])@:0
    (240)@http://localhost:1531/PureClientAjax/Scripts/AjaxLibrary/MicrosoftAjax.debug.js:50
    @:0

            fileName: http://localhost:1531/PureClientAjax/Samples/DebugTrace.htm
            lineNumber: 41

Ha már túl sokat naplóztunk, meghívhatjuk a clearTrace metódust a trace log takarítására:

    <input type="button" value="Trace törlése" onclick="Sys.Debug.clearTrace();" />

Assert

A Sys.Debug osztály utolsó metódusa az assert, amely akkor kiabál, ha a megadott feltétel hamis. Ha a hibaüzenet utáni harmadik paraméterben true-t adunk meg, a hiba ablakban a hibázó metódus kódja is megjelenik:

    var i = 1;    
    Sys.Debug.assert( i < 0, "Nem lehet pozitív!", true );

Ebben a menetben a piros pontot az IE kapja, mert karakterhelyesen megjeleníti a függvény teljes kódját, a FF viszont kicsapja belőle a kommenteket, áttördeli a kapcsos zárójeleket, ráadásul a magyar ékezetes karaketerek helyett csak kódjukat jeleníti meg, ami bizony nehezíti az olvasást, én ugyanis nem ezt írtam:

Talán így már nem annyira rémisztő a JavaScript írás smile_wink

 

Technorati tags: ,

Microsoft AJAX Library – ASP.NET nélkül

Ahogy az már a februári MSDN Kompetenciák Egyetemén is elhangzott, a Microsoft AJAX megoldásának egyik pillére a Microsoft AJAX Library. Ez a komponens lényegében három JavaScript fájl, amely az ASP.NET AJAX szerver oldali szolgáltatásaitól (UpdatePanel, webszolgáltatások stb.) függetlenül is használható, másként fogalmazva megáll a saját lábán, nem kell hozzá ASP.NET, sőt akár más szerver oldali technológiákkal (pl. PHP-vel) is összeházasíthatjuk.

Hogy bizonyítsuk a Microsoft AJAX Library szerver függetlenségét, ágyazzuk be nyers HTML oldalba! Lépések:

  1. A Microsoft AJAX Library script fájljatit tartalmazó ZIP letöltése és kibontása.
  2. Egy üres HTML oldal létrehozása.
  3. Szkript referenciák megadása a HTML oldalon. Amire szükség lehet:
    • Gyakran elég a MicrosoftAjax.js.
    • Ha extrákat is akarunk használni, akkor ne sajnáljuk kibányászni a Futures FTP-ből a preview scripteket. Kontrollok kezeléséhez a PreviewScript.js, csilivili animációkhoz pedig a PreviewGlitz.js kell.
    • Hibakereséshez nem baj, ha kéznél van a scriptek debug változatai is. Sőt, nálam az animációk csak a PreviewGlitz.debug.js fájllal mentek, a release verzióval nem!
  4. Az oldal alján inicializáljuk az AJAX Libraryt azzal, hogy meghívjuk a Sys.Application.initialize() metódust.
  5. Ellenőrzés: ha mindent jól csináltunk, akkor meg fog hívódni a pageLoad() metódusunk, amiben már a $get() függvény működni fog.

A teljes oldal kódja (feltételezve, hogy a szkriptek a Scripts mappában vannak):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Kezdőlap</title>
    
    <!-- Microsoft AJAX runtime -->
    <script type="text/javascript" src="Scripts/MicrosoftAjax.js"></script>
    <script type="text/javascript" src="Scripts/PreviewScript.js" ></script>
    
    <script language="javascript" type="text/javascript">
        // Automatikusan meghívódik, amikor az oldal betöltődött
        function pageLoad()
        {
            var txtName = new Sys.Preview.UI.TextBox( $get( "txtName" ) );
            Sys.Preview.UI.Window.messageBox( txtName.get_text() );
        }    
    </script>        
    
</head>

<body>
    <div>
        Az Ön neve:
        <input id="txtName" type="text" value="Szia Világ!" />
    </div>    

    <!-- Microsoft AJAX runtime inicializálása -->
    <script language="javascript" type="text/javascript">
        Sys.Application.initialize();
    </script>
</body>
</html>

Buktatók (ha nem működne):

  • Nem mindegy, hogy milyen sorrendben vannak a <script> tag-ek és az sem, hogy a <head> vagy a <body> részei.
  • A <script> nem működik úgy, ha önmagát zárjuk be, kell a különálló zárótag, tehát <script … /> nem jó, csak <script …></script> működik. Vajon miért? smile_sarcastic
  • Néhány dolog használható az AJAX Library-ben az initialize() meghívása nélkül is, de ha ott van, akkor legyen az oldal végén.

A legszebb az egészben, hogy az eredmény nem csak szerver, hanem böngésző független is (legalábbis amit az AJAX Library támogat), kipróbáltam Firefoxban, működik!

Mi mindent tud még az AJAX Library? Aki eljön a március 31-i Web Konferenciára, kaphat egy kis ízelítőt! smile_wink

 

Technorati tags: ,