Kas yra Angular ir kodėl verta jį mokytis?
Angular – tai ne tik dar vienas JavaScript karkasas. Tai visavertė platforma, kurią sukūrė Google ir kuri šiandien naudojama didelėse korporacinėse aplikacijose visame pasaulyje. Jei kada nors bandėte sukurti sudėtingą vieno puslapio aplikaciją (SPA) su grynuoju JavaScript ar net jQuery, tikriausiai žinote, kaip greitai kodas virsta netvarkingu spaghetti. Angular sprendžia šią problemą – jis primeta struktūrą, suteikia įrankius ir leidžia kurti aplikacijas, kurias galima prižiūrėti ir plėsti.
Verta iš karto pasakyti: Angular nėra lengviausias dalykas pradedantiesiems. Lyginant su React ar Vue, jo mokymosi kreivė yra gerokai statesnė. Bet tai nereiškia, kad jo nereikėtų mokytis – priešingai, kai supranti Angular principus, daugelis kitų technologijų atrodo paprastesnės. Be to, Angular žinios rinkoje vis dar labai vertinamos, ypač dirbant su didelėmis komandomis ir enterprise lygio projektais.
Angular naudoja TypeScript – tai JavaScript superset’as, kuris prideda statinį tipizavimą. Iš pradžių tai gali atrodyti kaip papildoma našta, bet tikėkite – po kelių savaičių suprasite, kodėl tai yra didžiulis privalumas. Klaidos aptinkamos dar prieš paleidžiant kodą, IDE pagalba tampa daug galingesnė, o kodas tampa aiškesnis.
Aplinkos paruošimas ir pirmasis projektas
Prieš pradedant, reikia susitvarkyti su aplinka. Čia nėra nieko sudėtingo, bet reikia žinoti tvarką:
Pirma, įsitikinkite, kad turite įdiegtą Node.js. Angular CLI reikalauja Node.js, ir rekomenduojama naudoti LTS versiją – ne pačią naujausią, nes kartais naujesnės versijos dar nebūna pilnai suderintos su Angular ekosistema. Patikrinkite versiją terminale:
node --version
npm --versionTada įdiekite Angular CLI globaliai:
npm install -g @angular/cliAngular CLI yra jūsų geriausias draugas. Jis generuoja komponentus, servisus, modulius ir dar daug ką – tereikia žinoti komandas. Naujas projektas kuriamas taip:
ng new mano-projektas
cd mano-projektas
ng serveKai paleidžiate ng serve, aplikacija pasiekiama per http://localhost:4200. Kas įdomu – Angular turi hot reload funkciją, tai reiškia, kad keičiant kodą naršyklė atsinaujina automatiškai. Tai labai pagreitina kūrimo procesą.
Projekto struktūra iš pradžių gali atrodyti bauginančiai – daug failų, daug aplankų. Bet iš esmės svarbiausia yra src/app aplankas. Ten gyvena jūsų aplikacijos logika. app.module.ts – tai pagrindinis modulis, kuris registruoja viską, ką naudoja aplikacija. app.component.ts – tai šakninis komponentas.
Komponentai – Angular širdis
Jei Angular reikėtų paaiškinti vienu sakiniu: tai komponentais pagrįsta architektūra. Viskas yra komponentas – mygtukas, navigacijos juosta, forma, visas puslapis. Komponentai yra kaip LEGO kaladėlės – kuriate mažas, nepriklausomas dalis ir jas sudedame į vieną visumą.
Komponentas Angular’e susideda iš trijų dalių:
- TypeScript klasė – čia rašoma logika, duomenys, metodai
- HTML šablonas – tai, ką vartotojas mato
- CSS stiliai – kaip tai atrodo
Naujas komponentas generuojamas su CLI:
ng generate component mano-komponentas
// arba trumpiau:
ng g c mano-komponentasTai sukuria keturis failus: .ts, .html, .css ir .spec.ts (testams). Pagrindinis komponentas atrodo maždaug taip:
import { Component } from '@angular/core';
@Component({
selector: 'app-mano-komponentas',
templateUrl: './mano-komponentas.component.html',
styleUrls: ['./mano-komponentas.component.css']
})
export class ManoKomponentas {
pavadinimas: string = 'Labas, Angular!';
skaicius: number = 0;
padidinti(): void {
this.skaicius++;
}
}Dekoratorius @Component nurodo Angular, kad ši klasė yra komponentas. selector – tai HTML žymė, kuria naudosite šį komponentą kitų komponentų šablonuose. Jei selector yra app-mano-komponentas, tai šabloną naudosite taip: <app-mano-komponentas></app-mano-komponentas>.
Vienas svarbus dalykas, kurį reikia suprasti nuo pat pradžių: Angular komponentai turi gyvavimo ciklą (lifecycle). Svarbiausi metodai:
ngOnInit()– iškviečiamas, kai komponentas inicializuojamas. Čia dažniausiai kraunami duomenys iš API.ngOnDestroy()– iškviečiamas prieš sunaikinant komponentą. Čia reikia atsisakyti subscription’ų, kad išvengtumėte atminties nutekėjimo.ngOnChanges()– iškviečiamas, kai keičiasi įvesties duomenys.
Data Binding – kaip komponentas kalba su šablonu
Data binding yra mechanizmas, leidžiantis sinchronizuoti duomenis tarp TypeScript klasės ir HTML šablono. Angular turi kelis data binding tipus, ir juos suprasti yra labai svarbu.
Interpoliacija – paprasčiausias būdas rodyti duomenis šablone:
<h1>{{ pavadinimas }}</h1>
<p>Skaicius: {{ skaicius }}</p>Property binding – leidžia dinamiškai nustatyti HTML elemento savybes:
<img [src]="nuotraukosUrl" [alt]="pavadinimas">
<button [disabled]="yraUzblokuotas">Spausk</button>Event binding – reaguoja į vartotojo veiksmus:
<button (click)="padidinti()">Padidinti</button>
<input (keyup)="apdorotiIvestį($event)">Two-way binding – tai dvikryptis ryšys, kai duomenys sinchronizuojami abiem kryptimis. Naudojamas dažniausiai su formų elementais:
<input [(ngModel)]="vardas">
<p>Jūs įvedėte: {{ vardas }}</p>Kad veiktų ngModel, reikia importuoti FormsModule į savo modulį. Tai dažna klaida pradedantiesiems – importuoja komponentą, bet pamiršta modulį.
Praktinis patarimas: nenaudokite two-way binding ten, kur pakanka vienpusio. Two-way binding yra patogus, bet gali sukelti sunkiai sekamuosius šalutinius efektus sudėtingesnėse aplikacijose. Reactive Forms (apie jas kalbėsime vėliau) yra geresnė alternatyva sudėtingiems formų scenarijams.
Servisai ir priklausomybių įterpimas
Komponentai turėtų rūpintis tik tuo, kas rodoma vartotojui. Verslo logika, duomenų gavimas iš API, duomenų transformavimas – visa tai turėtų būti servisuose. Tai ne tik gera praktika – tai Angular filosofija.
Servisas generuojamas taip:
ng generate service duomenys
// arba:
ng g s duomenysPaprastas servisas gali atrodyti taip:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DuomenyService {
private apiUrl = 'https://api.pavyzdys.lt';
constructor(private http: HttpClient) {}
gautiVartotojus(): Observable<any[]> {
return this.http.get<any[]>(`${this.apiUrl}/vartotojai`);
}
}Dekoratorius @Injectable({ providedIn: 'root' }) nurodo, kad šis servisas yra singleton – visoje aplikacijoje egzistuoja tik vienas jo egzempliorius. Tai labai svarbu suprasti, nes tai reiškia, kad servisas gali saugoti būseną, kuri prieinama iš bet kurio komponento.
Priklausomybių įterpimas (Dependency Injection) yra vienas iš Angular kertiniu principų. Vietoj to, kad patys kuriate serviso egzempliorių su new DuomenyService(), jūs tiesiog deklaruojate jį konstruktoriuje, ir Angular pats pasirūpina jo sukūrimu ir perdavimu:
export class ManoKomponentas implements OnInit {
vartotojai: any[] = [];
constructor(private duomenyService: DuomenyService) {}
ngOnInit(): void {
this.duomenyService.gautiVartotojus().subscribe(duomenys => {
this.vartotojai = duomenys;
});
}
}Čia matote ir RxJS – reaktyvaus programavimo biblioteka, kuri yra neatsiejama Angular dalis. Observable ir subscribe – tai pagrindinės sąvokos, kurias reikia suprasti. Observable yra kaip srautas duomenų, o subscribe – tai būdas „klausytis” to srauto. Svarbu: kai komponentas sunaikinamas, reikia atsisakyti subscription’ų, kitaip gausite atminties nutekėjimą. Naudokite takeUntilDestroyed() arba async pipe šablone.
Maršrutizavimas – navigacija tarp puslapių
Vieno puslapio aplikacijos neturi tradicinio puslapių perkrovimo – navigacija vyksta JavaScript lygmeniu. Angular Router leidžia apibrėžti maršrutus ir rodyti skirtingus komponentus priklausomai nuo URL.
Maršrutai dažniausiai apibrėžiami app-routing.module.ts faile:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { PagrindinisPuslapis } from './pagrindinis/pagrindinis.component';
import { VartotojiaiKomponentas } from './vartotojai/vartotojai.component';
import { DetaliosKomponentas } from './detalios/detalios.component';
const routes: Routes = [
{ path: '', component: PagrindinisPuslapis },
{ path: 'vartotojai', component: VartotojiaiKomponentas },
{ path: 'vartotojai/:id', component: DetaliosKomponentas },
{ path: '**', redirectTo: '' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}Šablone reikia nurodyti, kur bus rodomi komponentai:
<nav>
<a routerLink="/">Pagrindinis</a>
<a routerLink="/vartotojai">Vartotojai</a>
</nav>
<router-outlet></router-outlet><router-outlet> – tai vieta, kur Angular įterps aktyvų komponentą. routerLink direktyva naudojama vietoj įprasto href, nes ji neleidžia puslapiui persikrauti.
Dinaminiams maršrutams (pvz., /vartotojai/42) galite gauti parametrą komponente:
import { ActivatedRoute } from '@angular/router';
export class DetaliosKomponentas implements OnInit {
constructor(private route: ActivatedRoute) {}
ngOnInit(): void {
const id = this.route.snapshot.paramMap.get('id');
// arba reaktyviai:
this.route.paramMap.subscribe(params => {
const id = params.get('id');
});
}
}Vienas svarbus dalykas – lazy loading. Didelėse aplikacijose nereikia krauti viso kodo iš karto. Galite nustatyti, kad tam tikri moduliai būtų kraunami tik tada, kai vartotojas pereina į atitinkamą sekciją:
{
path: 'administracija',
loadChildren: () => import('./administracija/administracija.module')
.then(m => m.AdministracijaModule)
}Tai labai pagerina pradinį aplikacijos įkrovimo greitį.
Dažniausios klaidos ir kaip jų išvengti
Kiekvienas, pradedantis su Angular, daro panašias klaidas. Čia surinktos dažniausios, kad galėtumėte jų išvengti:
1. Pamiršti importuoti modulius. Jei naudojate ngModel, reikia FormsModule. Jei naudojate HTTP, reikia HttpClientModule. Jei naudojate Angular Material komponentus, kiekvienas jų turi savo modulį. Klaidos pranešimas dažniausiai būna kažkas panašaus į „Can’t bind to ‘ngModel’ since it isn’t a known property” – tai aiškus ženklas, kad trūksta modulio.
2. Subscription’ų neuždarymas. Jei komponente prisiregistruojate prie Observable ir neišsiregistruojate, kai komponentas sunaikinamas, gausite atminties nutekėjimą. Naudokite async pipe šablone – jis automatiškai tvarko subscription’ų gyvavimo ciklą:
<!-- Vietoj subscribe() komponente, naudokite async pipe šablone -->
<ul>
<li *ngFor="let vartotojas of vartotojai$ | async">
{{ vartotojas.vardas }}
</li>
</ul>3. Logikos dėjimas į komponentus. Komponentas turėtų tik rodyti duomenis ir reaguoti į vartotojo veiksmus. Visa verslo logika – į servisus. Jei jūsų komponentas turi daugiau nei 100 eilučių TypeScript kodo (neįskaitant šablono), tikriausiai kažkas negerai.
4. Change detection problemos. Angular naudoja change detection mechanizmą, kad žinotų, kada atnaujinti vaizdą. Kartais, ypač dirbant su asinchroniniais duomenimis ar trečiųjų šalių bibliotekų įvykiais, Angular nežino, kad duomenys pasikeitė. Sprendimas – naudoti ChangeDetectorRef.detectChanges() arba NgZone.run().
5. Netinkamas komponentų hierarchijos planavimas. Prieš pradedant koduoti, pagalvokite apie komponentų struktūrą. Kaip duomenys tekės tarp komponentų? Kas bus „smart” komponentai (su logika), kas bus „dumb” (tik rodo duomenis)? Geras planavimas sutaupo daug laiko vėliau.
6. Angular versijų painiojimas. AngularJS (1.x) ir Angular (2+) yra visiškai skirtingi karkasai. Kai ieškote informacijos internete, įsitikinkite, kad ji skirta jūsų naudojamai versijai. Daug senų Stack Overflow atsakymų yra apie AngularJS ir jie neveiks su moderniu Angular.
Nuo „Hello World” iki realaus projekto – ką daryti toliau
Jei pasiekėte šią dalį ir supratote viską, kas buvo parašyta aukščiau – puiku, turite tvirtą pagrindą. Bet Angular ekosistema yra daug platesnė, ir yra keletas temų, kurias tikrai verta išmokti toliau.
Reactive Forms – tai galingesnis formų valdymo būdas, lyginant su Template-driven Forms. Jis leidžia programiškai valdyti formas, lengviau rašyti validacijas ir testuoti. Didelėse aplikacijose Reactive Forms yra beveik būtinybė.
RxJS operatoriai – map, filter, switchMap, combineLatest, debounceTime ir daugelis kitų. Kuo geriau suprasite RxJS, tuo elegantiškesnį kodą rašysite. Ypač switchMap yra labai naudingas dirbant su HTTP užklausomis, kurios priklauso viena nuo kitos.
Angular Material – Google sukurta UI komponentų biblioteka Angular’ui. Jei neturite dizainerio komandoje arba tiesiog norite greitai sukurti gražiai atrodančią aplikaciją, Angular Material yra puikus pasirinkimas. Jame yra viskas – nuo mygtukų iki sudėtingų lentelių su rūšiavimu ir puslapiavimo.
NgRx – tai state management sprendimas Angular’ui, pagrįstas Redux principu. Jei aplikacija tampa sudėtinga ir duomenys turi būti dalinami tarp daugelio komponentų, NgRx gali padėti. Bet perspėjimas: NgRx prideda daug boilerplate kodo ir nėra reikalingas mažesnėms aplikacijoms. Pirmiausia išbandykite servisus su BehaviorSubject – dažnai to pakanka.
Testavimas – Angular turi puikią testavimo infrastruktūrą iš dėžutės. Jasmine ir Karma naudojami unit testams, Cypress ar Playwright – E2E testams. Testavimas Angular’e nėra taip sunku, kaip atrodo, ir jis tikrai verta laiko investicijos.
Praktinis mokymosi planas: pirmą savaitę – Angular pagrindai ir pirmasis projektas. Antrą savaitę – komponentai, data binding, direktyvos. Trečią savaitę – servisai, HTTP, RxJS pagrindai. Ketvirtą savaitę – maršrutizavimas, formų valdymas. Po mėnesio – sukurkite realų projektą, kad ir paprastą užduočių sąrašą su backend’u. Teorija be praktikos nieko verta.
Angular mokymosi kelias gali atrodyti ilgas, bet kiekvienas žingsnis atneša apčiuopiamų rezultatų. Pradėkite nuo mažo, nesistenkite iš karto suprasti visko, ir svarbiausia – rašykite kodą. Klaidos yra normali mokymosi proceso dalis, o Angular klaidos pranešimai, nors kartais ir gąsdinantys, dažniausiai tiksliai nurodo, kas negerai. Ir dar vienas dalykas: Angular dokumentacija yra viena geriausių tarp populiarių karkasų – naudokitės ja, ji tikrai verta laiko.






