Az Angular alkalmazások fejlesztése során gyakran találkozunk a viselkedésalapú alanyokkal (BehaviorSubject), amelyek segítségével kezelhetjük az aszinkron adatfolyamokat és biztosíthatjuk az adatok reagálóképességét az alkalmazás különböző részeiben. Azonban van egy újabb technológia, a Signals, amely hatékonyabban és könnyebben kezelheti az adatfolyamokat, miközben csökkenti az alkalmazás bonyolultságát és méretét. Ezen a ponton szeretnénk bemutatni, hogyan válthatunk a BehaviorSubject-ről Signals-re az Angular alkalmazásokban, és miért érdemes ezt megtenni.

A Signal-ek egy szinkron adatfeldolgozási folyamatot képviselnek, míg a BehaviorSubject aszinkron módon kezeli az adatokat. De vajon miért lehet a szinkron adatkezelés jobb választás, mint az aszinkron? Az aszinkron kód nagyobb erőforrást igényel, és gyakran lassabb a szinkron megoldásokhoz képest. A Signal-ek használata nemcsak gyorsabb és olcsóbb, hanem lehetőséget ad arra is, hogy az adatokat anélkül kezeljük, hogy blokkolnánk a kód többi részét. Ez különösen hasznos lehet kisebb és közepes méretű projektek esetében, amelyek nem igényelnek teljeskörű JavaScript keretrendszereket, mint például Angular, React vagy Vue.

A Signal-ek alkalmazásának bevezetéséhez a következő lépéseket kell végrehajtanunk. Az első lépés a WeatherService frissítése, hogy a currentWeather$ viselkedésalapú alanyt lecseréljük egy Signal-re. Az alábbi kódrészlet mutatja, hogyan kell ezt megtenni:

typescript
import { signal } from '@angular/core'
export class WeatherService implements IWeatherService {
readonly currentWeatherSignal = signal(defaultWeather) }

Ezután be kell vezetnünk egy új getCurrentWeatherAsPromise függvényt, amely az aszinkron adatfolyamot Promise formátumra konvertálja, és egy új updateCurrentWeatherSignal függvényt, amely aszinkron módon frissíti a Signal értékét:

typescript
import { ..., firstValueFrom } from 'rxjs' getCurrentWeatherAsPromise(searchText: string, country?: string): Promise<any> {
return firstValueFrom(this.getCurrentWeather(searchText, country))
}
async updateCurrentWeatherSignal(searchText: string, country?: string): Promise<void> { this.currentWeatherSignal.set(await this.getCurrentWeatherAsPromise(searchText, country)) }

Ezt követően frissítenünk kell a CurrentWeatherComponent-et, hogy a Signal értékét használja a viselkedésalapú alany helyett. Az alábbiakban látható, hogyan kell módosítani a kódban ezt a változást:

typescript
export class CurrentWeatherComponent { readonly currentSignal: WritableSignal constructor(private weatherService: WeatherService) {
this.currentSignal = this.weatherService.currentWeatherSignal
} }

A CitySearchComponent-et is módosítani kell, hogy az új szolgáltatási hívást váltsa ki:

typescript
export class CitySearchComponent { ... this.weatherService.updateCurrentWeatherSignal(searchText, country) ... }

Ezáltal az alkalmazásunkat sikeresen átalakítjuk úgy, hogy a Signal-ek kommunikáljanak az egyes komponensek között. A Signal-ek kevésbé összetettek, mint a BehaviorSubject, de a legtöbb esetben az extra funkcionalitások nincsenek kihasználva. A Signal-ek biztonságosak a memóriában, könnyűek, és lehetőséget biztosítanak új típusú alkalmazások létrehozására, mint például a korábban említett RxJS összeolvadás (merge) technika. Bár az RxJS és a Signal-ek komplementer technológiák, a legjobb eredmény elérése érdekében ajánlott egy átfogó átalakítást végrehajtani az alkalmazásban, ahogy azt a példák is mutatják.

Fontos megérteni, hogy a Signal-ek nem helyettesítik teljes mértékben az összes aszinkron adatkezelést, mint például a debouncing logikát a keresési mezőben. Ezért az RxJS-t nem érdemes teljesen elhagyni, de a Signal-ek használata biztosítja a könnyebb és hatékonyabb adatkezelést olyan helyzetekben, ahol nincs szükség bonyolult aszinkron műveletekre. Az Angular a toSignal és fromSignal interoperabilitási függvényeket is biztosít, de érdemes kerülni a két paradigma keverését. A legjobb eredmény elérése érdekében mindig teljes körű átalakítást végezzünk.

A fejlesztők számára, akik nem rendelkeznek elég tapasztalattal a Signal-ekkel vagy az RxJS-sel, talán úgy tűnik, hogy az AI-eszközök, mint a ChatGPT, segíthetnek az alkalmazások gyors generálásában. Az AI segítségével könnyedén létrehozhatunk egy alapvető alkalmazást, mint például egy időjárás-alkalmazás, és akár a felhasználói felületet is személyre szabhatjuk a kívánt dizájn szerint. Az AI képes arra, hogy a felhasználó által megadott specifikációk alapján kódot generáljon, amely azonnal alkalmazásba fordítható.

Egyes fejlesztők úgy vélik, hogy az ilyen eszközök révén könnyen helyettesíthetők a hagyományos fejlesztési módszerek. Azonban fontos felismerni, hogy bár az AI gyorsan generálhat kódot, a finomhangolás, az optimalizálás és a tervezés még mindig a fejlesztők feladata. Az AI nem helyettesítheti a fejlesztők tapasztalatát, és a kód minősége mindig az emberi kreativitás és a szakértelem függvénye marad.

Hogyan valósítsunk meg újrafelhasználható Angular űrlapkomponenseket és egyedi vezérlőket?

Az Angular fejlesztés során a komponensek újrafelhasználhatósága kulcsfontosságú a kód karbantarthatósága és bővíthetősége szempontjából. Egy hatékony megközelítés az űrlapok kezelésekor, hogy a közös logikát egy alap komponensbe helyezzük, amit aztán a specifikus komponensek örökölnek. Például a BaseFormComponent szolgálhat alapként, amely már tartalmazza az űrlapcsoportot (formGroup), az kezdeti adatokat (initialData), a letiltás funkciót (disable) és az űrlap készenléti állapotát (formReady). Ezzel az örökléssel elkerülhető az ismétlődő kód, és a fejlesztők számára egységes szabványokat lehet előírni.

Az új komponens létrehozásakor (például a NameInputComponent), amely a felhasználó névadatait kezeli, az osztályt a BaseFormComponent-ből kell származtatni, és implementálni kell a buildForm metódust, amely a FormBuilder segítségével hozza létre a formGroup-ot a megfelelő validációkkal. Ez az eljárás garantálja, hogy az összes ilyen komponens egységes szerkezetű, és könnyen karbantartható lesz. Az ngOnInit eseménykezelő biztosítja, hogy az űrlap megfelelően inicializálódjon, míg az ngOnChanges metódus a változásokra reagálva engedélyezi vagy letiltja az űrlapot, illetve frissíti az adatokat, így szinkronban tartva a komponens állapotát a külső változásokkal.

A ProfileComponent refaktorálása során a NameInputComponent-et már integrálhatjuk, hogy a profil név mezői egy önálló, újrafelhasználható komponensben kezelődjenek. Itt fontos az is, hogy a BehaviorSubject típusú nameInitialData$ tulajdonság biztosítsa az adatfolyamokat, és az űrlap állapota mindig naprakész legyen. A ngOnDestroy metódusban a deregisterAllForms segítségével egyszerűen felszabadíthatók az erőforrások, és megelőzhető a memória szivárgás.

Az adatbevitel minőségének javítása érdekében ajánlott az input maszk használata, amely korlátozza a felhasználók által bevitt adat formátumát, ezáltal csökkentve a hibák számát. Az ngx-mask könyvtár alkalmazása egyszerű és hatékony megoldást kínál, például telefonszám mezők validálására. A maszk beállítása a modulkörnyezetben vagy az alkalmazás konfigurációjában történik, a direktívák pedig a sablonban használhatók fel.

A szabványos vezérlők mellett az Angular lehetőséget ad egyedi vezérlők készítésére is a ControlValueAccessor interfész implementálásával. Ez biztosítja, hogy a saját komponensek zökkenőmentesen integrálódjanak az Angular űrlaprendszerébe, beleértve a validációs mechanizmusokat is. Egy példa erre a „Lemon Rater” nevű egyedi értékelő komponens, amely valós idejű interakciót tesz lehetővé, és vizuálisan is megjeleníti a felhasználó értékelését. Az ilyen egyedi vezérlők megvalósítása bár erőforrásigényes lehet, de jelentős mértékben növeli az alkalmazás felhasználói élményét, és egyedi arculatot kölcsönöz neki.

Fontos megérteni, hogy az űrlapkomponensek és egyedi vezérlők fejlesztésekor a kód újrafelhasználhatósága és a komponensek egységes viselkedése nem csupán a hatékonyságot növeli, hanem hozzájárul a stabilabb, megbízhatóbb alkalmazások létrehozásához. A bonyolultabb funkcionalitások esetén, mint például az adatváltozások szinkronizálása vagy az erőforrások felszabadítása, a megfelelő életciklus események és az öröklődési struktúrák tudatos alkalmazása elengedhetetlen. Ezen túl a használható validációk és input maszkok alkalmazásával jelentősen javítható az adatminőség és csökkenthető a hibalehetőség. A fejlesztők számára ajánlott az Angular dokumentáció és a külső könyvtárak (pl. ngx-mask) aktív követése, hogy az új fejlesztések beépítésével folyamatosan korszerűsítsék alkalmazásaikat.

Mi az Angular és miért érdemes vele dolgozni?

Az Angular egy nyílt forráskódú platform, amelyet a Google és egy fejlesztői közösség tart fenn. Jelentősen eltér az előző generációs AngularJS-től, amely egy monolitikus JavaScript SPA (Single Page Application) keretrendszer volt. Az Angular új generációja, az Angular 2+ egy sokoldalú platform, amely nemcsak böngészőkre, hanem hibrid mobil alkalmazásokra, asztali programokra és szerveroldali megjelenítésre is képes. Ez a váltás új lehetőségeket és rugalmasságot biztosít, melyek nélkülözhetetlenek a mai skálázható, vállalati szintű alkalmazások fejlesztésében.

A Google és a Microsoft együttműködésének eredményeként az Angular alapértelmezett nyelve a TypeScript lett, amely a JavaScript egy kiterjesztése. A TypeScript lehetővé teszi, hogy a fejlesztők modern JavaScript kódot írjanak, amely egyszerre kompatibilis a régebbi böngészőkkel, például az Internet Explorer 11-gyel, és a legújabb, úgynevezett „evergreen” böngészőkkel, mint a Chrome, Firefox vagy Edge. Ez az eszköz nemcsak a fejlesztői élményt javítja, hanem a karbantarthatóságot és a stabilitást is elősegíti.

Az AngularJS világában a frissítések kockázatosak és időigényesek voltak, mert minden új verzió új kódolási mintákat és kísérleti funkciókat hozott, amelyek gyakran a régi API-k elavulásával jártak. A verzióváltások üteme bizonytalan volt, és jelentős erőforrásokat emésztett fel a kód újraírása. Ennek eredményeként sok fejlesztő ragadt egy adott AngularJS verziónál, mert a migráció túl bonyolultnak bizonyult. 2018-ban a Google bejelentette az AngularJS 1.7-es verziójának utolsó jelentős frissítését, és 2022 januárjában hivatalosan is megszűnt a támogatás.

Az Angular platform ezt a helyzetet gyökeresen megváltoztatta: az Angular követi a szemantikus verziózás (semver) szabályait, amely garantálja, hogy a kisebb verziószám-növekedések új funkciókat és elavulási figyelmeztetéseket hoznak, de nem törik meg a kompatibilitást. A nagyobb verziók félévente jelennek meg, és ezek után 12 hónapon keresztül hosszú távú támogatást (LTS) kapnak hibajavításokkal és biztonsági frissítésekkel. Ez azt jelenti, hogy egy adott Angular verziót akár másfél évig is támogatnak, így a fejlesztők nyugodtan tervezhetnek, nem kell félnie az instabilitástól vagy az előre nem látható frissítésektől.

Az Angular fejlesztőcsapata szintén az automatikus frissítési eszközök fejlesztésére koncentrál, így a frissítések egyszerűbbé és kevésbé munkaigényessé váltak. Az „ng update” parancs bevezetése óta a fejlesztők automatizáltan, gyorsan és biztonságosan frissíthetik projektjeiket, így például egyes cégek akár 30 napról egy napra csökkentették az upgrade időt. Ez a kiszámítható, támogatott frissítési folyamat végre lehetővé teszi, hogy egy alkalmazás ne ragadjon le a régi verzióknál, hanem folyamatosan fejlődjön, anélkül, hogy teljes újraírást igényelne.

A Google és a Microsoft számára az Angular és a TypeScript ingyenes elérhetősége nem csupán marketingfogás, hanem stratégiai lépés. Egy kifinomult, könnyen használható keretrendszer fenntartása vonzza a tehetségeket, lehetővé teszi új technológiák kipróbálását millió fejlesztő bevonásával, és végső soron hozzájárul a cég üzleti sikereihez. A nyílt forráskódú megközelítés biztosítja, hogy a fejlesztők szabadon alakíthatják az eszközt, illetve elkerülhetik a drága, zárt technológiák támogatási költségeit.

Az Angular körüli információk keresésekor érdemes körültekintően eljárni, mert az AngularJS és az új Angular (néha Angular 2-nek vagy csak Angularnak nevezik) között jelentős különbségek vannak, és a régebbi verziókra vonatkozó tanácsok sokszor nem alkalmazhatók az újabb, 14-es vagy későbbi verziókra, különösen az Ivy renderelő motor bevezetése után. Az Angular hivatalos dokumentációja (https://angular.dev) a legmegbízhatóbb forrás, nem szabad összekeverni az AngularJS-hez tartozó angulajs.org oldallal vagy a korábbi angular.io-val.

Az Angular megtanulása jó befektetés, amely hosszú távon megtérül. Bár más keretrendszerek, mint a React vagy a Vue is népszerűek, és adott helyzetben jobban megfelelhetnek, az Angular komplex, átfogó megoldás, amely gyors fejlesztést és magas szintű támogatást biztosít. A fejlesztők számára az Angular egy stabil, előrelátható és jól karbantartható eszköz, amely nemcsak technikai, hanem szervezeti és üzleti szempontból is előnyös.

Fontos megérteni, hogy a modern Angular nem csupán egy egyszerű keretrendszer, hanem egy teljes fejlesztői platform, amely az alkalmazás minden rétegét lefedi és támogatja, az egyszerű webalkalmazásoktól a komplex vállalati rendszerekig. A folyamatos támogatás, a rendszeres, kiszámítható frissítések és az automatizált migrációs eszközök jelentősen csökkentik az alkalmazások fenntartási költségeit, és megkönnyítik a technológiai fejlődés követését.