1. diel - Úvod do AngularJS
Tento kurz je na historickú verziu frameworku Angular. Ak neudržiavate starší projekt, navštívte prosím kurzy pre aktuálnu verziu Angular.
Nástupom technológií HTML5 sa JavaScript nebývalo rozrástol. Aplikácia v tomto jazyku sa stávajú čím ďalej viac komplexné a samotná knižnica jQuery na to prestáva stačiť. Má totiž jednu veľkú nevýhodu a to, že mieša dohromady aplikačnú logiku, spracovanie udalostí a manipuláciu s DOM. Pri menších aplikácií, webových stránok či widgetov to zase taký problém nie je. Problém nastáva, ak sa daná aplikácia či widget rozrastie natoľko, že sa programátor začne v kóde strácať. V takom prípade nastupuje na rad architektúra MVC alebo nejaký jej derivát.
Keď sme sa teda rozhodli používať MVC architektúru, narazíme na pár problémov. Ako ju implementovať v JavaScripte a ako urobiť template systém? HTML je dobré pre deklaráciu statických dokumentov, ale čo keď potrebujeme vytvoriť dynamické aplikácie, kde sa informácie vo View (teda v HTML) neustále mení? AngularJS je MVC framework od Googlu, ktorý rozširuje HTML o rad elementov a atribútov, vďaka ktorým je vytvoriť taký dynamický HTML dokument hračka. Naviac umožňuje vytvárať vaše vlastné HTML elementy a atribúty, obsahuje two-way dáta binding a má veľa ďalších užitočných vlastností vďaka ktorým sa kód stáva extrémne prehľadný, jednoduchý a krátky.
Najlepšie bude, predviesť tento framework na konkrétnom príklade. Vytvoríme si tabuľku, do ktorej budeme môcť pridávať záznamy, radiť je a vyhľadávať medzi nimi. Pre obyčajný javascript alebo aj jQuery je táto úloha ťažšia, než sa na prvý pohľad zdá. Pre AngularJS je to však hračka.
Vytvoríme si teda základné HTML dokument.
<!DOCTYPE html> <html ng-app> <head> <meta charset="UTF-8" /> <title>Úvod do AngularJS | ITnetwork.cz</title> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script> <script type="text/javascript" src="js/controllers.js"></script> </head> <body ng-controller="FrameworksController"> <section> <header> <h1>Seznam frameworkù</h1> <input type="text" placeholder="hledaný výraz" id="search" ng-model="searchQuery" /> </header> <table> <thead> <tr> <th>ID</th> <th>Jméno</th> <th>Popis</th> <th>Jazyk</th> </tr> </thead> <tbody> <tr ng-repeat="fw in frameworks | filter:searchQuery "> <td>{{fw.id}}</td> <td><a ng-href="{{fw.link}}">{{fw.name}}</a></td> <td>{{fw.description}}</td> <td>{{fw.language}}</td> </tr> </tbody> </table> </section> </body> </html>
Na prvý pohľad klasický HTML dokument, ale niektoré elementy obsahujú špeciálne atribúty (direktívy), ktoré do klasického HTML nepatrí. Tieto direktívy spracováva Angular.
NgApp
Táto direktíva automaicky spustí našu aplikáciu. Ako parameter očakáva názov hlavného modulu aplikácie. My parameter zatiaľ vynecháme.
NgModel
Je direktíva, ktorá hovorí ANGULAR, aby použil two-way dáta binding. Všetky zmeny vo scope sa premietnu na tomto elementu a naopak, všetky zmeny hodnoty viazaného elementu sa prejaví vo scope. Funguje iba s elementmi input, select a textarea
{{AngularJS výraz}}
Výraz medzi dvoma zloženými zátvorkami tiež spracováva AngularJS.
Syntax je rovnaká ako syntax JavaScriptu. Môžete tu vypisovať hodnoty poľa,
objektu, premenné, volať funkcie a používať tzv. Filtre. Filtre sa
zapisujú za znak '|' a majú syntax
| jméno_filtru:argument1:argument2
. O filtroch si povieme viac
nabudúce.
NgRepeat
Je cyklus, ktorý prejde pole a pre každú iteráciu zopakuje prvok, ku
ktorému sa viaže (v našom prípade celý element tr
). Vytvára
vnútri elementu špeciálne premenné. Jednak premennú obsahujúce aktuálnu
položku poľa (fw
) a potom špeciálne premenné
$index
, ktorá obsahuje aktuálne index položky,
$first
je logická hodnota (true, ak je položka prvý v poli),
$middle
opäť logická hodnota (true ak položka medzi prvým a
posledným prvkom) a $last
. Všimnite si, že všetky premenné,
ktoré pridal angular, začínajú znakom dolára. Je to tak preto, aby
nevznikol konflikt medzi premennými pridanými nami a premennými Angular.
Výsledok ngRepeat sa dá filtrovať a radiť. To docielime špeciálnym Filter
filter. Ako argument očakáva text, podľa ktorého bude poľa filtrovať. My
mu odovzdáme premennú searchQuery
.
NgController
Odovzdá danému elementu scope Controlleru, ktorého mu odovzdáme parametrom. Teda iba meno Controlleru.
Model a Controller
V AngularJS je modelom akýkoľvek objekt odovzdaný do scope. V našom prípade to bude len pole objektov s danými informáciami. Vytvoríme ho v Controlleru na objekte $ scope, ktorý Controlleru odovzdáme (resp. AngularJS odovzdá) parametrom. Samotný controller bude predstavovať JS funkcie.
function FrameworksController( $scope ) { $scope.frameworks = [{ "id" : 1, "name" : "AngularJS", "link" : "http://www.angularjs.org", "description" : "HTML enhanced for web apps!", "language" : "javascript" }, { "id" : 2, "name" : "jQuery", "link" : "http://www.jquery.com", "description" : "Write less, do more", "language" : "javascript" }, { "id" : 3, "name" : "RaphaelJS", "link" : "http://www.raphaeljs.com", "description" : "Kreslete vektorovou grafiku javascriptem", "language" : "javascript" }]; };
Aj keď controller sám zatiaľ nič moc nerobí, plní tú dôležitú úlohu. Poskytuje priestor, kam môžeme uložiť informácie, teda scope. Každý scope v Controlleru je potomkom root scope (teda koreňového scope). Scope je veľmi dôležitý. AngularJS ho používa, aby oddelil model, controller a view ale zároveň je udržiaval synchronizované. Ak sa zmení scope v dáta modelu, premietnu sa zmeny v šablóne a obrátene, ak sa zmenia scope v šablóne, zmení sa tiež aj v dáta modelu (viz. Art týmto odsekom). Toto je veľmi užitočná vlastnosť ANGULAR vďaka ktorej máme vždy k dispozícii aktuálne informácie.
One-way data binding
Two-way data binding v AngularJS
Spracovanie formulára
Keď už máme tabuľku našich obľúbených frameworkov, bolo by dobré, aby sme ich mohli ďalej pridávať. Vytvoríme preto formulár.
<form ng-submit="addFramework()"> <input type="text" ng-model="data.name" placeholder="Jméno frameworku" /> <input type="text" ng-model="data.link" placeholder="Odkaz na web" /> <select ng-model="data.language"> <option value="" disabled="disabled">Programovací jazyk ...</option> <option value="javascript">JavaScript</option> <option value="java">Java</option> <option value="c#">C#</option> <option value="php">PHP</option> <option value="python">Python</option> </select> <textarea placeholder="Krátký popis" ng-model="data.description"></textarea> <input type="submit" value="Pøidat" /> </form>
Aj v tomto formulári sa objavili nám ešte nepoznáme atribúty. Direktívu ngModel už poznáme. Len by som podotkol, že ak premenná uvedené v ngModel neexistuje, Angular ju sám v danom scope vytvorí. Dáta z nášho fomulár budeme ukladať do objektu dáta.
NgSubmit
Táto direktíva spracováva javascriptovú udalosť onSubmit. V parametri je AngularJS výraz. Môžeme tu teda nastaviť hodnotu premenným alebo spúšťať funkcie v našom scope. Rovnako možno použiť aj direktívy ngClick, ngMouseover atp. V podstate všetky základné JS udalosti.
Poznámka: V aktuálnej verzii AngularJS (1.0.1) ešte neexistuje direktíva ngFocus a ngBlur. Tie budú pridané do verzie 1.2 (pozri. AngularJS 1.0 -> 1.2 Roadmap)
Musíme ešte vytvoriť zodpovedajúce metódu addFramework
v
našom Controlleru FrameworksController
. Táto metóda pridá
objekt dáta do nášho poľa a vynuluje ho. Tak zmizne aj dáta v našom
formulári a pridá sa nový záznam do tabuľky.
$scope.addFramework = function() { // Přiřadíme záznamu číslo ID $scope.data.id = $scope.frameworks.length+1; // Vložíme objekt data do pole frameworků $scope.frameworks.push($scope.data); // a vynulujeme ho $scope.data = {}; };
Teraz už môžeme pridávať nové zaznie cez tento formulár. Avšak toto je len základná práca s formulármi v AngularJS. Pokročilejšie manipulácia s nimi ako sú rôzne validácia atp. si ukážeme niekedy inokedy.
Sledovanie zmien vo scope
Niekedy je potrebné sledovať zmeny objektov vo scope a podľa toho rozhodnúť, čo sa bude diať. Scope má na takéto prípady špeciálnu metódu $ watch. V parametroch táto funkcia chce názov hodnoty, ktorú sledujeme, funkciu, ktorá sa vykoná pri každej zmene a či má porovnávať objekty.
V našej aplikácii by bolo dobré ukladať frameworky do nejakého úložisko, aby sa nám náš zoznam nezmazal po každom obnovení stránky. K tomu môžeme použiť napríklad localStorage. Aby sme tak neprišli o naše záznamy v tabuľke, vytvoríme si watcher v našom Controlleru sledujúci poľa frameworkov a pri každej jeho zmene uložíme novú hodnotu do localStorage.
$scope.$watch( // Budeme sledovat změny v ojektu frameworks 'frameworks', // Funkce má v parametrech aktuální a starý seznam frameworků function( newList, oldList ) { // a uložíme je do lokálního uložiště jako localStorage.setItem('frameworks', JSON.stringify(newList)); }, // Porovnáváme dva objekty true );
Teraz sa nám informácie ukladajú na lokálnej úložisko, tak by bolo
dobré ich odtiaľ pri každom načítaní aplikácie vytiahnuť. Jednoducho
nastavíme v Controlleru
$scope.frameworks = JSON.parse(localStorage.getItem('frameworks')) || [];
Radenie ngRepeat a dokončenie aplikácie
Už sme skoro u konca. Teraz si skúsime len zoradiť tabuľku po kliknutí
na nadpise príslušného stĺpca. V ngRepeat môžeme okrem filtra
filter
Použiteľná aj filter orderBy
, ktorý zoradí
pole podľa zadaných hodnôt. Tie sú dve, jednak meno vlastnosti, podľa
ktorej chceme polia zosadiť (napr. Name, id, description atď. - zodpovedá
kľúčom objektu) a potom či má pole zoradiť vzostupne alebo zostupne
(logická hodnota - nie je povinná). Pridáme teda tento filter k výrazu
direktívy ngRepeat:
ng-repeat="fw in frameworks | filter:searchQuery | orderBy:orderProp:reverse"
.
Tak zoradíme polia vždy podľa hodnoty premennej orderProp
a
reverse
. Ak nebudú definované v našom scope, nebude pole
zoradené, takže je ani definovať nemusíme. Avšak ak by ste chceli mať pole
zoradené, stačí vytvoriť v scope danej premennej.
Teraz len nastaviť premenné orderProp
a reverse
po kliknutí na záhlavie každého stĺpca našej tabuľky. Na to použijeme
direktívu ngClick, ktorá sa chová rovnako ako už spomínaná direktíva
ngSubmit, akurát spracováva inú udalosť (onClick). Zmeníme hlavičky našej
tabuľky.
<thead> <tr> <th ng-click="orderProp = 'id'; reverse = !reverse;">ID</th> <th ng-click="orderProp = 'name'; reverse = !reverse;">Jméno</th> <th ng-click="orderProp = 'description'; reverse = !reverse;">Popis</th> <th ng-click="orderProp = 'language'; reverse = !reverse;">Jazyk</th> </tr> </thead>
Tak a máme hotovo. Máme funkčnú tabuľku, ktorá ide radiť, možno v nej vyhľadávať a dokonca aj pridávať záznamy, bez toho aby sa zmazali po obnovení stránky. Nakoniec k článku prikladám k stiahnutiu zdrojové kódy aplikácie. Zaujímavé na tejto aplikácii je fakt, že CSS štýly sú niekoľkokrát väčšie ako HTML štruktúra a kód Controlleru dohromady. Viac sa o AngularJS dozviete na oficiálnych stranách AngularJS.org.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 1789x (3.94 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript