JavaScript címkéhez tartozó bejegyzések

Mi lesz veled, Angular? Gondolatok az Angular Connect 2017 után

Angular Connect WelcomeA héten volt szerencsém részt venni a Londonban rendezett két napos Angular Connect 2017 konferencián, ebben a blog bejegyzésben pedig néhány ott hallott gondolatot és benyomást jegyzek fel részint magamnak emlékeztetőül, részint mert másnak is hasznosak lehetnek.

Az itt leírtak közül több nem szó szerint így hangzott el az előadók szájából, ez már az én kivonatom. A fontosabb előadásokról videófelvétel készült, azok megtekinthetőek a konferencia honlapján, az tekinthető hiteles forrásnak.

Át kell állni Angular@latest-re

Tisztán látszik, hogy a Google nagyon komolyan veszi az Angulart. Nem egyszerűen egy szabadidőben készülő open source projektről van szó, hanem egy olyan technológiáról, amibe azért invesztálnak, mert ők maguk is használják. Az egyik legnagyobb projektjük, a Google Cloud Console több, mint 10 ezer TypeScript és 3 ezer Angular fájlt tartalmaz.

Ez nem újdonság, így volt ez már az AngularJS idején is, ám ebből rögtön két dolog is következik.

Az első, hogy a fejlesztés nem áll meg. Jó elvek szerint készült, és stabil alapokon áll már az Angular, ezért látványos új funkciókkal egyre ritkábban fogunk találkozni, viszont a motorháztető alatt folyamatos fejlesztések történnek minden verzióban. Itt a legfontosabb célterület a teljesítmény, aminek egyik összetevője az első oldalbetöltés ideje (Time To Interactive), a másik pedig az alkalmazás futása közbeni sebesség. Egyik területen sem muzsikál rosszul az Angular már most sem, de a csapat nem állt meg, minden verzióban egyre kisebb a bundle és egyre gyorsabb az app.

Ehhez az kell, hogy nagyon sok energiát öljön a fejlesztőcsapat abba, hogy a fordító egyre okosabb legyen. Csak egy példa: a Build Optimizer a TypeScript fordító sajátosságait és képességeit kihasználva tovább pofozza a kódot annak érdekében, hogy a minification még hatékonyabb legyen. Olyan trükköket csinál a kód variálásával, amivel egy átlagos projektben egy átlagos fejlesztő biztosan nem foglalkozna, Google méretekben viszont már sokat számít, mi pedig élvezhetjük a sok munka és kutatás eredményeit.

A második következménye annak, hogy a Google komolyan használja az Angulart, hogy a folyamatos upgrade-nek egyszerűnek kell lennie. A fejlesztő csapat szerint az Angular API stabil, nem várhatók breaking change-ek, a v4-ről v5-re történő átállás például a legtöbb projektnél egyszerű verzió szám átírás a package.json-ban, és máris új fordítót kap az app és gyorsabban fog futni. A Google alkalmazásainak eddig 25%-át migrálták át Angularra.

Adott tehát egy olyan keretrendszer, ami minden verzióban egyre hatékonyabb lesz, és a készítők szerint nem lesz nehéz az átállás az újabb verziókra. Tegyük még hozzá azt a tényt, hogy az Angular fejlesztők száma már meghaladja az AngularJS fejlesztők számát, és hogy az AngularJS-be valószínűleg már sokáig nem fog invesztálni a Google és máris ott tartunk, hogy az élő projekteket célszerű átmigrálni Angularra, és folyamatosan frissíteni a legújabb verzióra, azaz most v5-re.

Upgrade, de hogyan?

Angular upgradeKérdés, hogy mit kezdjünk a meglévő AngularJS kódbázissal, hogyan vigyük át Angularra?

Hogy upgrade vagy újraírás a jó megoldás, arra nincs egyértelmű, minden esetre működő válasz. A hivatalos álláspont szerint meg kell vizsgálni a kódbázis sajátosságait és a jövőbeli várható üzleti elvárásokat, és ezeknek a fényében kell dönteni. Ez egyáltalán nem új és nem meglepő.

Nincs meglepetés sajnos azzal kapcsolatban sem, hogy az upgrade-et hogyan érdemes kivitelezni. Nincs varázsszer, az ngUpgrade "az" eszköz, legfeljebb azt lehet variálni, hogy milyen lépésben haladunk. Ha az alkalmazásunk több "oldalból" áll, akkor érdemes lehet route-onként haladni.

Összességében tehát az upgrade területén nincs más lehetőségünk, mint időt allokálni rá, és végigcsinálni. Itt szerintem a legtöbb projektben nem a mérnöki, hanem a menedzsment oldal fogja a nehézséget jelenteni.

Mit kezdjünk a nagy kódbázissal?

BazelA folyamatosan bővülő kódbázis egyre nagyobb kihívást jelent. Növekszik a repository mérete, növekszik a fordítási idő, egyre több csapat dolgozik ugyanazon a kódon, egyre nagyobb problémát okoz a függőségek kezelése. Mit lehet tenni?

A Google és a Facebook a monorepo híve, az alkalmazások és a library-k egyetlen nagy repository-ban vannak, míg az Amazonnál és a Netflixnél a microrepository-ban hisznek, ott minden független egymástól. Bármelyiket is valljuk, a választás feltételekhez kötött.

A Google részben nyilvánossá tette a saját fejlesztésű build eszközét, a Bazelt, aminek az erőssége, hogy a kód módosításai után csak azt fordítja újra, amire kihatással lehet. Ha nincs publikus API változás, akkor csak az adott komponenst, ha van, akkor pedig azokat, amik arra épülnek. Így elérték, hogy az edit-and-refresh élmény 2 másodperc alatt legyen. Ehhez persze az is kellett, hogy a kódot okosan szervezzék. Átlagosan náluk 1 package-ben 1 Angular modul van, 1 modul pedig átlagosan 1.5 komponenst tartalmaz. Ezzel nem csak azt nyerik, hogy gyors a build, hanem azt is, hogy tiszták az interfészek és dokumentáltak a függőségek.

Továbbá érdemes megnézni, hogy az Angular.io webhely buildeléséhez milyen megoldásokat választottak, és abból mit tudunk felhasználni. Ez az Angular alkalmazás náluk az állatorvosi ló, sok benchmark erre vonatkozik.

DRY vagy PRY?

A Don’t Repeat Yourself elv szerint üldözni kell minden kód duplikációt, ha valahol ismétlődő kódot találunk, akkor azt azonnal refaktorálnunk kell.

Ám ha ezt túl korán tesszük meg, lábon lőhetjük magunkat. A közös kódrészlet függőséget jelent, az interfésze contractként kezelendő, aminek a változásait csak megfelelő körültekintéssel és kommunikációval lehet elvégezni.

Ha van megbízható CI infrastruktúránk és jó teszt lefedettségünk, akkor ez költséges, de nem kockázatos. Kiszervezzük a közös kódot egy saját package-be, és ha bármi változik a package-ben, akkor újrafordítunk minden olyan alkalmazást és package-et, ami arra épül és újra is teszteljük azokat.

Ám ha nem vagyunk ilyen szerencsés helyzetben, akkor a túl korán alkalmazott DRY nem csak költséges, de kockázatos is lehet. Amíg tehát egy kódrészlet gyakran változik, addig inkább a Please Repeat Yourself (PRY) elvet érdemes követni, és csak a stabilizálódott kódokat kiszervezni közös helyre.

Mielőtt azonban vallást váltunk és elkezdjük követni a PRY elvet, érdemes feltenni magunknak a kérdést: vajon vissza fogunk-e térni később, és refaktoráljuk-e a már stabil kódrészletünket, vagy a jól működő dolgokhoz általában nem nyúlunk?

Zárójelben jegyzem meg, hogy a build eszközeink (TypeScript compiler, Angular compiler, Build Optimizer, minifier, Webpack stb.) nagyon agresszíven törekszenek a duplikáció kiszűrésére, “mutatványos környezetben” (production) tehát nem nagy a veszteség.

Hogyan teszteljünk nagy kódbázist?

CucumberA tesztelés terén nem tartogatott meglepetéseket a konferencia. Volt ugyan egy előadás a SerenityJS-ről, ami nem a Protractorban megszokott Page Objects elvet követi, hanem a Screenplay Patternt, de engem nem győzött meg.

Egyrészt azért, mert szerintem a Page Object módszert is lehet úgy használni, hogy a felsorolt problémákat elkerülje (kód mérete, olvashatósága, duplikációk stb.), másrészt pedig azért, mert nem látom, hogy ez miért jobb, mint a jól bevált Gherkin-Cucumber páros.

Ami viszont fontos – bár nem új – gondolat az előadásból, hogy a teszteket igenis tervezni kell. A jól megtervezett teszt esetekből lesznek a jól megtervezett teszt implementációk, azaz a karbantartható teszt kód.

Mi várható 2018-ban?

A fordító és a runtime folyamatos fejlesztésén kívül az Angular csapat természetesen újabb funkciókkal is bővíti a keretrendszert, amiből a PWA, az Angular Universal és az Angular Elements kapott nagyobb teret a konferencián.

PWA

PWAA PWA, vagy teljes nevén Progressive Web Apps, a legújabb (?) név arra a jelenségre, hogy webes technológiákkal készített és az interneten hosztolt programkód olyan felhasználói élményt nyújtson, mint egy telepített, vastag kliens alkalmazás. Technológiai szinten az újdonságot a Service Worker jelenti, ami biztosítja az offline működés feltételeit. Ezt a komponenst az Angular csapat becsomagolta egy @angular/service-worker package-be, ami lehetővé teszi, hogy nagyon kényelmesen készítsünk Angularral PWA-t. A CLI 1.6 bétájában már megjelenik a –service-worker kapcsoló, későbbi verziókban pedig várható, hogy ez lesz az alapértelmezett, tehát érdemes készülni rá.

A PWA nem egy fekete-fehér terület, vannak hátrányai (például verzió frissítés), ami miatt egyáltalán nem biztos, hogy minden esetben megéri használni. Érdemes viszont megismerkedni vele és szem előtt tartani mint lehetőséget (és mint biztonsági tényezőt is), mert jelentősen növelhetjük vele a felhasználói élményt.

Angular Universal

Angular Universal

A 4.0 verziótól már az Angular részeként elérhető Angular Universal célja, hogy platform és eszköz támogatást adjon szerver oldali HTML renderelés megvalósításához. A feladat nem csak annyi, hogy a backendről érkező HTML sztringet beszúrunk a weboldal közepére, hanem támogatni kell a kereső motorokat és az oldalról tartalmat kiollózó egyéb alkalmazásokat (pl. Facebook, Slack), miközben többféle stratégiát (pl. statikus renderelés fordításkor) is kell tudnia támogatni.

Olyan környezetben, ahol a teljesítmény problémákat okoz, érdemes megismerkedni a fogalommal és az Angularos megvalósítással.

Angular Elements

Angular LabsA szoftverfejlesztés egyik problémája, hogy általában le kell tenni a voksunkat valamelyik keretrendszer mellett, és utána annak a szabályai szerint kell játszanunk. Különösen bosszantó ez egy olyan környezetben, mint a web, ahol mindegy, hogy milyen kliens oldali platformot választunk, végül mezei HTML és JavaScript kód fog futni a böngészőben, miközben az egyes keretrendszerek között nincs, vagy csak nagyon körülményes az átjárás.

Ezen a problémán próbál segíteni az egyelőre csak az Angular Labs részeként elérhető Angular Elements, aminek az a célja, hogy a Custom Elements szabvány lehetőségeit felhasználva úgy csomagolja be az Angularos komponenseinket, hogy más keretrendszerek számára standard HTML elementnek tűnjenek. A kezdeményezés még nagyon gyerekcipőben jár, jövőre lehet belőle valami, mindenesetre üdítő látvány, hogy az Angular csapat nem zárkózik be, nyitott más platformok felé, és támogatni akarja a library fejlesztőket.

Ezek voltak a visszatérő témák, de ezeken kívül még sok más terület is terítékre került: forms, animations, DevKit, Schematics, ABC, Query, DI, aria, internationalization, flex layout, security, burnout, VR – szerencsére a videók mind megtekinthetők a Youtube-on. Mindkét nap keynote-tal kezdődött, érdemes megnézni őket.

Ráadásként az Angular csapat egy ígéretet is tett: kigyomlálják a Github repóban található közel 2000 issue-t és több, mint 300 PR-t. Külön embert vettek fel erre 🙂

 

Technorati-címkék: ,,,
Reklámok

Öröklésnél elveszik az Error message tulajdonsága

Ilyen kódot már mindenki látott:

try {
  throw new Error('Oh, nooooo!');
} catch (e) {
  console.log(e.message);            // Oh, nooooo!
  console.log(e instanceof Error);   // true
}

Ha nagyon sok hasonló keletkezik, akkor előbb-utóbb az ember rájön, hogy szükség lenne saját hiba osztályokra, még JavaScriptben is. Jó ötletnek tűnhet valahogy így létrehozni egyet:

function OhNoooError() {
  Error.call(this, "Oh, nooooo!");
  this.name = "OhNoooError";
}

Az eredmény azonban meglepő lehet:

try {
  throw new OhNoooError();
} catch (e) {
  console.log(e.message);                 // undefined
  console.log(e instanceof OhNoooError);  // true
  console.log(e instanceof Error);        // false
}

Az elkapott kivételünk ugyanis nem számít klasszikus Errornak (nem abból származik), és elveszítette a message tulajdonságát is.

Íme egy módszer, amivel ezeket a hibákat orvosolni lehet:

OhNoooError.prototype = Object.create(Error.prototype);
OhNoooError.prototype.constructor = OhNoooError;

function OhNoooError() {
  this.message = "Oh, nooooo!";
  this.name = "OhNoooError";
}

A kimenet is szebb lesz:

try {
  throw new OhNoooError();
} catch (e) {
  console.log(e.message);                 // Oh, nooooo!
  console.log(e instanceof OhNoooError);  // true
  console.log(e instanceof Error);        // true
}

A lényeg tehát, hogy a message tulajdonságot kézzel kell beállítani. Ha az öröklést esetleg CoffeeScriptben az extends kulcsszóval valósítjuk meg, a message tulajdonsággal akkor is manuálisan kell elbánnunk.

 

Technorati-címkék: ,

Ingyenes e-book Windows (Phone) 8.1 fejlesztéshez

2843.9780735611111f_7E0540F4A Windows 8 megjelenésével egy időben adta ki a Microsoft Press Kraig Brockschmidt Programming Windows Store Apps with HTML, CSS and JavaScript c. könyvét ingyenes e-book formájában. A 8.1 verzió megjelenésével a könyv kissé elavult, de szerencsére Kraig nem csüggedve tovább dolgozott rajta.

Most jelent meg a könyv második kiadása, amely 478 oldallal kibővítve immár a Windows 8.1 újdonságait is lefedi, sőt jelentős része alkalmazható Windows Phone 8.1 fejlesztéseknél is. A teljes könyv így 1311 oldalas lett, és szerencsére továbbra is ingyenesen tölthető le a Microsoft Virtual Academy oldaláról a kapcsolódó példakódokkal együtt.

 

Tetszőleges kiterjesztés megadása fájl mentésekor

Windows 8 alatt a File Open Picker dialógusablaknak viszonylag egyszerűen megadhatjuk, hogy tetszőleges típusú fájlt kiválaszthat a felhasználó, egyszerűen használjuk a szokásos csillagot:

var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
openPicker.fileTypeFilter.replaceAll(["*"]);

Ha azt szeretnénk, hogy a felhasználó tetszőleges kiterjesztéssel menthesse el a fájlt, a fentiek alapján megpróbálkozhatunk ezzel:

var savePicker = new Windows.Storage.Pickers.FileSavePicker();
savePicker.fileTypeChoices.insert("Tetszőleges", ["*"]);

Ám ez hibára vezet:

0x80070057 – JavaScript runtime error: The parameter is incorrect.

WinRT information: This file picker does not allow the all files extension.

No, ez pech. Szerencsére van megoldás, írjuk ezt:

savePicker.fileTypeChoices.insert("Tetszőleges", ["."]);
Technorati-címkék: ,,,

Ajaxos fájl feltöltés

Időnként felmerül, hogy jó lenne úgy feltölteni egy fájlt, hogy közben az oldal többi része nem változik, magyarul Ajaxosan. Rossz hírem van, az XMLHttpRequest objektum Level 1 változata ezt nem tudja, tehát ha régebbi böngészőkre is tekintettel kell lennünk, akkor nincs mese trükközni kell.

A legelterjedtebb trükközési módszer az iframe alkalmazása, azt ugyanis bátran lehet postbackelni, az egyetlen szépséghiba, hogy a válasz, például validációs hibák is az iframe-be fognak megérkezni. Tehát ha rejtett iframe-mel dolgozunk, akkor a választ onnan ki kell venni, és az oldal megfelelő részén meg kell jeleníteni. Van tehát feladat bőven, szerencsére a jQuery Form Plugin sokat tud segíteni a megvalósításban.

Először is készítsünk egy view-modelt szerver oldalon, amiben egy HttpPostedFileBase típusú tulajdonság fogja képviselni a feltöltött fájlt. Mellécsaptam még egy kötelező Name tulajdonságot, csak úgy a demonstráció kedvéért:

public class UploadVM
{
    [Required( ErrorMessage = "Please enter a name!" )]
    public string Name { get; set; }

    [Attachment]
    public HttpPostedFileBase Attachment { get; set; }
}

Az [Attachment] a korábbi cikkben bemutatott, fájl validálásra használt attribútum. Ellenőrzi, hogy van-e feltöltve fájl, illetve hogy helyes a kiterjesztése és nem túl nagy-e a mérete.

Ehhez a modellhez már készíthetünk egy űrlapot, ami fel fogja küldeni a fájlt és a megadott nevet:

@using( Html.BeginForm( "Index", "Home", FormMethod.Post, 
        new { id = "myForm", enctype = "multipart/form-data" } ) )
{
    <p>
        <label for="txtName">Name:</label>
        <input type="text" id="txtName" name="Name" />
    </p>

    <p>
        <label for="fupAttachment">File:</label>
        <input type="file" id="fupAttachment" name="Attachment" />
    </p>

    <p>
        <input type="submit" value="Upload" />
    </p>    

    <div id="errors"></div>
}

Fontos, hogy a generált formnak multipart/form-data értékű enctype attribútuma legyen, mert azzal tud csak fájl utazni, illetve létrehoztam még egy errors azonosítójú div-et is, ahol majd a hibaüzeneteket fogjuk megjeleníteni.

Ez az űrlap a HomeController Index nevű actionjére lő, amit így implementálhatunk:

[HttpPost]
public ActionResult Index( UploadVM model )
{
  if( !this.ModelState.IsValid )
  {
    string firstError = ModelState.First( m => m.Value.Errors.Any() )
                                  .Value.Errors[ 0 ].ErrorMessage;
    return this.FileUploadFailure( firstError );
  }

  // Process the file here

  string message = String.Format( "The file '{0}' is successfully uploaded.", 
                                  model.Name );
  return this.FileUploadSuccess( message );
}

Ha a view-model valamelyik tulajdonsága hibás, akkor az attribútumoknak köszönhetően a hibák bekerülnek a ModelStatebe, amit a metódus elején szokás szerint ellenőrzünk. Ha van hiba, akkor az első hibaüzenettel térünk vissza, ha nincs, akkor pedig feldolgozzuk a fájlt és egy siker üzenettel térünk vissza.

A visszatérési érték egy JSON objektum, mert ezt tudjuk kliens oldalon barátságosan feldolgozni. Csakhogy ne feledjük, hogy a válasz egy iframe-be fog beíródni, és nem minden böngésző szeret iframe-be application/json típusú tartalmat kapni. Szerencsére a jQuery Form Plugin támogatja azt a trükköt, hogy a JSON tartalmat egy <textarea> elembe ágyazva küldjük vissza a szerverre text/html típusú válaszként, onnan ő majd kiveszi a JSON tartalmat.

Hogy ez a csomagolás egyszerű legyen, készítettem egy saját result típust:

public class FileUploadJsonResult : JsonResult
{
  public override void ExecuteResult( ControllerContext context )
  {
    this.ContentType = "text/html";
    context.HttpContext.Response.Write( "<textarea>" );
    base.ExecuteResult( context );
    context.HttpContext.Response.Write( "</textarea>" );
  }
}

Az egyszerű példányosításhoz pedig két bővítő metódust, melyek közül az egyikkel sikert, a másikkal hibát lehet jelezni:

public static FileUploadJsonResult FileUploadSuccess( 
  this Controller controller, string successMessage = null )
{
  return new FileUploadJsonResult
  {
    Data = new { Success = true, Message = successMessage }
  };
}

public static FileUploadJsonResult FileUploadFailure( 
  this Controller controller, string errorMessage )
{
  return new FileUploadJsonResult
  {
    Data = new { Success = false, Message = errorMessage }
  };
}

Itt a Data tulajdonságban bármilyen szerkezetű objektumot összerakhatunk, az fog megérkezni válaszként a kliensre JSON formátumban. Itt most az egyszerűség kedvéért egy Success tulajdonságban jelzem, hogy a feltöltés hibátlanul megtörtént-e, és egy Message tulajdonságban hibaüzenetet vagy sikeres feltöltésre utaló üzenetet küldök vissza, amit a böngésző megjeleníthet.

Készen vagyunk tehát a szerver oldallal: van egy formunk, ami elPOSTolható egy actionnek, ami validálja a feltöltött tartalmat, és ha minden mező érvényes adatot tartalmaz, akkor feldolgozza őket, és az eredményt JSON válaszban jelzi.

Már csak a kliens oldal van hátra, amit természetesen a jQuery Form Plugin segítségével valósítunk meg. Ahogy a neve is mutatja, ez egy jQuery plugin, amit a form elemet burkoló jQuery objektumra (itt épp $form) kell ráhúznunk:

$form.ajaxForm({
    iframe: true,
    dataType: "json",
    beforeSubmit: function () {
      // TODO     },
    success: function (result) {
      // TODO 
    },
    error: function () {
      // TODO 
    }
});

Az alábbi eseménykezelőket célszerű megvalósítanunk:

  • beforeSubmit: ez a POST elküldése előtt fut le, itt írhatjuk ki például, hogy a feltöltés folyamatban van, vagy például a jQuery BlockUI plugin segítségével letilthatjuk az űrlapon lévő vezérlőket.
  • success: ez akkor hívódik meg, ha látszólag hibátlan volt a feltöltés, bár tapasztalatom szerint akkor is meg tud hívódni, ha a szerver valamilyen hibát jelez. Ha nem volt hiba, akkor a paraméterül kapott változóban a szerverről visszaküldött JSON objektum jelenik meg, de számítsunk rá, hogy hiba esetén ez lehet undefined is!
  • error: hiba esetén ez fut le.

Íme egy példa a success callback implementálására:

if (!result) {
$errors.html('<div class="validation-summary-errors"><ul><li>Oooops....
                </li></ul></div>');
}
else {
  $form.resetForm();

  if (result.Success === true) {
    var message = result.Message;
    if (message && message.length > 0) {
      $errors.html( message );
    }
  }
  else {
    $errors.html('<div class="validation-summary-errors"><ul><li>{0}
                  </li></ul></div>'.format(result.Message));
  }
}

Ebben a kódban a hibák megjelenítését egy kicsit összetett HTML darabkával végezzük. Ennek az a jelentősége, hogy a klasszikus ASP.NET MVC-s validálás is pont ilyen HTML-t generál magából, tehát a mi Ajaxos hibáink is pont ugyanolyan stílussal fognak megjelenni.

A format egy a szerver oldali String.Formathoz hasonló függvény, amit például így implementálhatunk JavaScriptben:

String.prototype.format = function () {
  var args = arguments;
  return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (m, n) {
    if (m === "{{") { return "{"; }
    if (m === "}}") { return "}"; }
    return args[n];
  });
};

Ha a szerverről nem csak az első, hanem összes ModelState hibát visszaadnánk, akkor egy ciklusban renderelhetnénk ki őket.

A cikkhez tartozó forráskód rengeteg kommenttel letölthető innen: http://sdrv.ms/10QQLSp

 

Technorati-címkék: ,

A jQuery szakít a régi IE verziókkal

jquery-logoMa megjelent a jQuery legújabb, 1.9 verziója és vele együtt a 2.0 verzió bétája. Bár a két verziónak ugyanaz az API-ja (pár dolgot az 1.9-ből éppúgy kivettek, mint a 2.0-ból), mégis óriási különbség van közöttük:

  • Az 1.9 verzió – a korábbiakhoz hasonlóan – fut Internet Explorer 6, 7 és 8 verziókon, ahogy ők mondják “oldIE”-n.
  • A 2.0 nem fog futni oldIE-n. Ez számos egyszerűsítést tett lehetővé, aminek köszönhetően a 2.0 verzió gyorsabb és kisebb lesz, mint az 1.9 verzió.

A Release Notes szerint a fejlesztők mindkét verziót támogatni fogják a jövőben, de én úgy sejtem, hogy ahogy az lenni szokott, ez nem lesz mindig így. Előbb-utóbb az 1.9 el fog avulni, az új funkciók pedig könnyen lehet, hogy csak a 2.0 verzióba fognak bekerülni.

Vajon ez kinek rosszabb, az IE-nek vagy a jQuery-nek? A fejlesztők fognak átállni a jQuery-ről más könyvtárra, vagy a weboldalak fognak lemondani a régi Internet Explorer támogatásáról?

 

Technorati-címkék: ,,

WinJS trükkök: Access is denied hiba egymásba ágyazott üzenet ablakoknál

A WinJS trükkök sorozat korábbi epizódjaiban megismerkedtünk az üzenet ablakok és a hozzájuk tartozó egyedi gombok létrehozásával. A tanultak alapján meg is írhatjuk az alábbi kódunkat, ami két MessageDialog ablakot jelenít meg egymás után:

var dlg = new MessageDialog( 'Első üzenet' );

dlg.commands.append( new UICommand( 'Bezár', function() {
  new MessageDialog( 'Második üzenet' ).showAsync().then( function() {
    // Itt csinálunk valami hasznosat...
  } );
} ) );

dlg.showAsync();

Ezzel a kóddal csak az a gond, hogy irgalmatlanul elszáll, méghozzá a legapróbb hibaüzenet nélkül. Debug módban futtatva az alkalmazást már látszik, hogy egy Access is denied kezeletlen kivétellel van dolgunk:

MessageDialog-Access-denied

Megvan a hiba? Ha nincs, akkor érdemes lehet megnézni a WinJS Trükkök sorozat mai epizódját, amiből nem csak az ok, hanem az is kiderül, hogyan lehet megszabadulni tőle:

(720p, teljes képernyős nézet ajánlott)

 

Technorati-címkék: ,,,,