AngularJS (1. alapok)


Már egy ideje ígérgetem, hogy írok egy rövid bejegyzést arról, hogy mi is az AngularJS. Amikor elsőnek találkoztam vele, úgy jellemezte valaki a rendszert, hogy ilyen lenne a HTML nyelv, ha most találták volna fel. Tehát felfoghatjuk akár a jelenlegi szabvány felokosításának is.

Kicsit jobban kifejtve az AngularJS egy nagyon szépen megkonstruált MVC keretrendszer. Ez valami baromi misztikus dolognak hangzik, pedig nem az. Az MVC a Model View Controller hármas rövidítése. és mostanában tulajdonképpen szinte minden adatokat kezelő alkalmazás ezt a felépítést használja. Az MVC annyit jelent, hogy az alkalmazást három rétegre osztjuk. Az adattartalomra (model), a megjelenítésre (view), és a működésre (controller). Ezek a rétegek körkörösen hivatkoznak egymásra. Az adattartalmat (model) a view réteg jeleníti meg, ahonnan mindenféle felhasználói események hatására meghívódik valami működés (controller), ami megváltoztatja az adattartalmat, és itt körbe is ért az egész. Talán még így is ködös kicsit az egész, úgyhogy nézzünk egy példát. Egy sima todo listát, ahová új elemeket lehet felvenni, és törölni onnan (mint mondjuk egy bevásárló lista). Itt ugye az adattartalom (model) az a lista, ami a todo elemeket tartalmazza. A view az ezt megjelenítő felhasználói felület. A cotroller pedig az eseménykezelők összessége, tehát hogy mit kell csinálni hozzáadáskor, illetve elem törlésekor. Így már úgy nagyjából talán világos, hogy mi az az MVC, de hogy valósul meg ez AngularJS-ben?

AngularJS-ben a model réteget JavaScript változók adják. Ezek tárolják az adatokat. A view réteget a HTML kód adja, amit az AngularJS saját attribútumokkal egészít ki. Innen jött ugye a bejegyzés elején említett dolog, tehát hogy fel lehet fogni az AngularJS-t a HTML nyelv felokosításának is. Ezek az attribútumok rendelik össze a model-t a view-val (tehát hogy hol milyen adatot kell megjeleníteni), illetve a controllerrel (hogy milyen eseményre mit kell reagálni). A controller réteget JavaScript függvények adják, amik a model réteget adó JavaScript változókat manipulálják, és ezzel teljes is a kép.

Lássunk is pár példát. Ehhez látogassunk el a http://angularjs.org helyre, és tekerjük kicsit le az oldalt a második HTML kódig (az 'Add Some Control' címet keressük). Ez pont az a todo alkalmazás, amit a példában is említettem. Nézzük hogyan is épül fel. Kattintsunk át a todo.js fülre. Itt látunk egy TodoCtrl nevű függvényt (valójában inkább osztály, de JavaScriptben ezek összemosódnak). Ennek van egy $scope nevű paramétere. Ennek részletezésébe most annyira nem akarok belemenni, mert nagyon elnyúlna a bejegyzés, de lényeg, hogy minden változót (model), és működést leíró függvényt (controller) ehhez kell majd hozzárendelnünk. Rögtön a kód elején láthatjuk is a todos változó kezdeti értékének beállítását. Itt a todos változóba két érték kerül, az egyik egy todo elem, ami már le van zárva, a másik pedig egy még nem teljesült todo elem. Az előbbiek fényében már gondolom mindenki tudja, hogy ebben az alkalmazásban ez a todos változó a model réteg szerepét tölti be. A változón túl van még 3 függvény. Ezek képezik a controller réteget. Az addTodo egy új elemet ad a listához, az archive pedig törli a már teljesült elemeket. Hát, a remaining olyan öszvér fajta, mert igaz, hogy függvény, de igazából adatot ad vissza (pontosan azt adja vissza, hogy hány elvégzendő feladat van), amit a felületen kijelzünk, tehát inkább a model rétegbe sorolnám. Most kattintsunk át a html nézetre. Itt láthatjuk a view réteget, és az összerendeléseket, ami az AngularJS igazi ereje. A kód elején van egy ng-app attribútum. Ez minden AngularJS alkalmazás elejére kell, ez jelöli ki azt a részt, ahol a speciális attribútumokat értelmezni kell. Ebben az esetben ez a teljes html kódra vonatkozik. Aztán van két script rész, ahol behivatkozzuk az AngularJS-t magát, illetve a controller-t tartalmazó javascript állományt. Eztán jön egy ng-controller attribútum, mivel az előbb definiált controllert egy html blokkhoz rendeljük. Ha a HTML oldal olyan felépítésű, akkor megtehetjük, hogy egyes részeihez más más controller-t rendelünk, vagy ezeket akár egymásba is ágyazhatjuk, de ilyesmivel most ne bonyolítsuk az életünket. Az ng-controller-es div-en belül vannak {{ és }} jelek közti szakaszok. Ezekkel dinamikus tartalmat illeszthetünk be a HTML kódba, ráadásul nemesen egyszerű módon. Egyszerűen ha itt megadjuk egy $scope-hoz rendelt változó nevét, akkor a rendszer ide behelyettesíti annak tartalmát, illetve ugyanez történik, ha valamilyen függvény hívást írunk a jelek közé (tulajdonképpen ide bármilyen egyszerűbb JavaScript kifejezést írhatunk). Utóbbira példa a {{remining()}} rész, előbbire pedig a {{todos.length}}. Ez tehát egy módja a model bekötésének. Eztán jön egy link ng-click attribútummal. Ez egy szép példa a controller bekötésére. Leírja, hogy egy esemény hatására milyen működésnek kell életbe lépnie. Ha ugye erre a linkre kattintunk (archive), akkor az archive() függvényt kell meghívni a $scope-ból. Eztán jön egy ng-repeat rész, ami megintcsak a  model bekötésének módja. Ez végigszalad a megadott változón, és közben egy másik változó minden körben felveszi az aktuális elem értékét. Itt ugye a todos változón szaladunk végig. Minden körben generálódik egy li elem, és a todo változó felveszi az aktuális elem értékét. A li elemben találunk egy checkbox-ot, amihez ng-model-el van hozzárendelve a todo elem done változója. Míg a {{}} jelek használata egyirányú összerendelés (csak odaírja a rendszer a változó tartalmát), addig az ng-model kétirányú. Tehát egyfelől az elem a változó tartalmának megfelelően viselkedik, másfelől a változó az elem állapotának megfelelő értéket kapja. Olyan mint ha innentől a változó a HTML elem leképződése lenne, ebben az esetben a checkbox-é. Ha a változó értéke változik, változik a checkbox állapota is, illetve ha a felhasználó változtat a checkbox állapotán, akkor változik a változó értéke is. A következő span részben az elem class-ja a todo.done-tól függ. Ez az egyszerű {{}} jeles behelyettesítés. Amire érdemes felfigyelni, hogy az egész dolog teljesen real-time. Tehát mikor beklikkeljük a checkbox-ot, és megváltozik a változó értéke, akkor vele együtt minden változóhoz kötött dolog is változik. Tehát jelen esetben az elem class-a is. Ezt ki is próbálhatjuk, ha jobb oldalon a checkbox-ra kattintunk. Nem kell azzal vesződnünk, mint mondjuk jQuery esetén, hogy a bejelölés eseményre rakjunk egy eseménykezelőt, ami megváltoztatja a másik elem class-át. Ezzel sokkal rövidebb, szebb, és tisztább kódot kapunk. Végül pedig van egy ng-submit eseménykezelő, ami az add gomb megnyomására meghívja az addTodo függvényt, ami berakja az új todo elemet, aminek tartalma az előtte lévő text elemben lévő ng-model attribútumnak hála a todoText változóba kerül.  

Hát, nagyon tömören ennyit akartam írni az alapokról. Az AngularJS nagyon sok mindent tud még ezen kívül. Definiálhatunk modulokat, saját attribútumokat, kommunikálhatunk a szerverrel, stb. de ezeknek már talán érdemes új bejegyzést szentelni. 

#blog   #angularjs  

Embedded Link

AngularJS — Superheroic JavaScript MVW Framework

AngularJS is what HTML would have been, had it been designed for building web-apps. Declarative templates with data-binding, MVW, MVVM, MVC, dependency injection and great ...