Fiszki Online Angular (Preview)
Darmowy podgląd 15 z 50 dostępnych pytań
Podstawowe zagadnienia
Czym jest Angular?
Angular to oparty na TypeScript otwarty framework do pisania aplikacji webowych stworzony i utrzymywany przez Google.
Główny nacisk jest położony na szybkość tworzenia aplikacji i ułatwienie wiązania komponentów z modelem danych.
Do najważniejszych zalet korzystania z Angulara należą:
- Mechanizm wstrzykiwania zależności (ang. dependency injection) ułatwiający konfigurowanie aplikacji
- Dynamiczny mechanizm szablonów (ang. templates)
- Dwukierunkowy przepływ danych w aplikacji
- Dostęp do wielu funkcjonalności bez konieczności konfiguracji i korzystania z dodatkowych bibliotek, np. routing, zarządzanie stanem, RxJS, HTTP
- Szeroka dostępność narzędzi programistycznych i zewnętrznych bibliotek
Co odróżnia Angular od AngularJS?
| AngularJS | Angular |
|---|---|
| Wykorzystanie JavaScript | Wykorzystanie TypeScript |
| Architektura MVC | Architektura oparta na komponentach |
| Brak wsparcia dla aplikacji mobilnych | Wsparcie dla aplikacji mobilnych |
| Brak wsparcia dla SSR | Wsparcie dla SSR przez Angular Universal |
| Wykorzystanie ng-model oraz ng-bind | Wykorzystanie ngModel oraz [] i () |
| Wykorzystanie kontrolerów | Wykorzystanie komponentów |
Jakie są elementy składowe Angulara?
Do najważniejszych składowych Angulara należą:
- Komponenty (ang. components)
- Dyrektywy (ang. directives)
- Serwisy (ang. services)
- Moduły (ang. modules)
- Szablony (ang. templates)
- Metadane (ang. metadata)
- Mechanizm Routingu
- Mechanizm wiązania danych (ang. data binding)
- Mechanizm wstrzykiwania zależności (ang. dependency injection)
Komponenty
Czym jest komponent?
Komponent (ang. component) to klasa oznaczona dekoratorem @Component opisująca fragment UI aplikacji. Składa się z dyrektywy powiązanej z szablonem. W przeciwieństwie do innych dyrektyw, tylko jeden komponent może być przypisany do pojedynczego elementu DOM.
Aplikacja ma przynajmniej jeden root component, który łączy drzewo komponentów z modelem DOM.
Każdy komponent musi być częścią NgModule, aby mógł zostać zrenderowany. W tym celu należy go dodać do listy declarations w metadanych NgModule.
Zachowanie komponentów można kontrolować za pomocą ich cyklu życia, który rozpoczyna się, gdy Angular inicjalizuje komponent i zaczyna go renderować razem ze wszystkimi komponentami zależnymi.
↑ Powrót na góręW jaki sposób dwa komponenty mogą się komunikować?
W Angularze dwa komponenty mogą się komunikować na kilka sposobów:
- Za pomocą dekoratora
@Input()komponent rodzica może przekazywać dane do komponentu dziecka - Za pomocą dekoratora
@Output()orazEventEmitterakomponent dziecka może przekazywać dane do komponentu rodzica - Za pomocą dekoratora
@ViewChild()komponent rodzica może uzyskać dostęp do danych komponentu dziecka - Za pomocą wspólnej instancji serwisu wstrzykniętego do obu komponentów
- Za pomocą współdzielonego obiektu
Subject<T>
Dyrektywy
Do czego służą dyrektywy?
Dyrektywa (ang. directive) to klasa oznaczona dekoratorem @Directive(). Gdy Angular renderuje szablon, modyfikuje drzewo DOM zgodnie z instrukcjami określonymi przez dyrektywy. Określają one w jaki sposób elementy DOM powinny być dodawane lub modyfikowane.
Dyrektywy, podobnie do komponentów, posiadają swój cykl życia, z którego można skorzystać, aby zaimplementować lub skonfigurować ich zachowanie.
Wyróżniamy dwa rodzaje dyrektyw: strukturalne i atrybutowe.
Można również tworzyć własne dyrektywy za pomocą dekoratora @Directive().
Do najczęściej używanych dyrektyw należą: ngFor, ngIf, ngModel, ngStyle, ngClass.
Jakie znasz rodzaje dyrektyw?
Dyrektywy dzielimy na trzy rodzaje:
- Strukturalne (ang. structural directives) - zmieniają układ elementów DOM przez dodanie nowych elementów oraz usunięcie lub podmianę istniejących, np. dyrektywy
*ngFor,*ngIf - Atrybutowe (ang. attribute directives) - zmieniają wygląd lub zachowanie istniejących elementów DOM, np. dyrektywy
ngStylelubngClass. W kodzie szablonów wyglądają jak zwykłe atrybuty HTML - Komponenty - dyrektywy z dołączonym szablonem
<li *ngFor="let fund of managedFunds"></li>
<app-fund *ngIf="fundActive"></app-fund>
<input type="text" formControlName="currency" fundCurrency />
↑ Powrót na górę
Pipe
Do czego służy Pipe?
Pipe to klasa reprezentująca prostą funkcję formatującą dane w szablonach, np. liczby, waluty, daty lub złożone obiekty.
Może przyjmować parametry oraz łączyć się z innymi Pipe w łańcuchy wywołań, np.:
{{ fund.launchDate | date:'fullDate' | uppercase }}Angular zawiera zestaw wbudowanych implementacji, m.in: DatePipe, CurrencyPipe, DecimalPipe, ale można również napisać własną implementując interfejs PipeTransform:
@Pipe({name: 'courseDate'})
export class CourseDate implements PipeTransform {
transform(value: string) {
return moment(value)
.format('DD/MM/YY').toUpperCase();
}
}
↑ Powrót na górę
Do czego służy AsyncPipe?
AsyncPipe to wbudowana w Angular implementacja Pipe służąca do obsługi danych odbieranych asynchronicznie.
Przyjmuje jako parametr wejściowy Observable<T> lub Promise, automatycznie się do niego subskrybuje i zwraca najnowszą wartość, którą to źródło emituje.
Bez AsyncPipe, komponent musiałby sam zarządzać subskrypcją, odbieraniem danych od Observable oraz pamiętać o odsubskrybowaniu się na koniec, aby zapobiec wyciekom pamięci.
<div *ngFor='let fund of (funds$ | async)'>
{{ fund.name }}
</div>
↑ Powrót na górę
Change detection
Jak działa mechanizm change detection?
Change detection jest procesem synchronizowania widoku z danymi. Proces w uproszczeniu działa według schematu:
- Angular porównuje bieżący stan danych z poprzednio zapamiętanym i zbiera wszystkie zmiany
- Wywołuje
ngOnInit,ngOnChangesingDoCheckz komponentów dzieci - Aktualizuje DOM komponentu aby odzwierciedlić zmiany w modelu
- Uruchamia change detection dla komponentów dzieci
- Wywołuje
ngAfterViewInitz komponentów dzieci
Change detection domyślnie nie przeprowadza głębokiego porównania złożonych obiektów. Porównywane są tylko wartości prymitywne, lub referencje do obiektów.
↑ Powrót na góręJakie znasz strategie change detection?
Wykorzystywane są dwie strategie change detection:
ChangeDetectionStrategy.Default– Domyślna strategia CheckAlways, w której wszystkie komponenty w drzewie komponentów (od czubka drzewa po sam dół) są sprawdzane pod kątem zmian przy każdym uruchomieniu change detectionChangeDetectionStrategy.OnPush– Strategia CheckOnce, w której sprawdzanie wywoływane jest tylko na żądanie, lub gdy zmieni się referencja do obiektu powiązanego z widokiem; dzięki temu można uniknąć niepotrzebnego sprawdzania wartości komponentu i wszystkich komponentów dzieci
Dependency Injection
Jak działa Dependency Injection?
Mechanizm wstrzykiwania zależności (ang. Dependency Injection) to wzorzec projektowy, w którym klasa deklaruje zależności których potrzebuje zamiast tworzyć je samemu.
Wymagane zależności zostaną wstrzyknięte w momencie tworzenia obiektów tej klasy.
W Angularze mechanizm składa się z dwóch części:
- Injector – gdy Angular tworzy komponent, serwis, dyrektywę, która potrzebuje zależności np. do zewnętrznego serwisu, najpierw sprawdza czy injector posiada instancję tego serwisu; jeżeli taka nie istnieje injector użyje odpowiedniego providera, aby ją utworzyć
- Provider – obiekt, który posiada informację o tym, jak pobrać lub utworzyć zależność
Reactive Programming
Jaka jest różnica między Observable a Promise?
| Promise | Observable |
|---|---|
| Eager - wykonuje się od razu po utworzeniu | Lazy - wykonuje się dopiero, gdy pojawi się subskrybent |
Łączenie za pomocą Promise.then() | Łączenie za pomocą operatorów RxJS |
| Obsługa nie może zostać przerwana | Obsługa może zostać przerwana przez wywołanie unsubscribe() |
| Dostarcza tylko jednej wartości | Dostarcza strumienia wielu wartości przez dłuższy czas |
Co różni switchMap od concatMap i mergeMap?
Przykładowo, gdy chcemy wysłać żądanie HTTP dla każdej wartości pochodzącej z Observable.of('a', 'b', 'c'):
switchMap– najważniejsza jest najnowsza wartość emitowana przez Observable, dlatego wcześniejsze żądania HTTP dla'a'i'b'są anulowane, gdy wyemitowana zostanie wartość'c'; jest to przydatne do obsługi HTTP GET, gdzie również interesuje nas tylko najnowsze żądanieconcatMap– w przeciwieństwie doswitchMapnie anuluje poprzednich, trwających jeszcze żądań, ale za to zachowuje kolejność wykonania i nie rozpocznie kolejnego żądania dopóki poprzednie się nie zakończyło, co przypomina HTTP POST lub PUTmergeMap- wykona wszystkie żądania nie czekając na zakończenie poprzednich, co przydaje się przy obsłudze żądań HTTP DELETE, gdzie interesuje nas efekt końcowy
Optymalizacja
Jak zoptymalizować aplikację napisaną w Angularze?
Można to zrobić na wiele sposobów, np:
- Włączyć kompilację AOT (domyślne od Angular 9), która przyspieszy ładowanie strony
- Skonfigurować lazy loading dla tzw. feature modułów
- Stosować
ChangeDetectionStrategy.OnPushoraz tworzyć nowe obiekty zamiast je modyfikować, co przyspieszy działanie change detection - Podzielić zależności aplikacji na
dependenciesidevDependencies - Usunąć nieużywane subskrypcje podczas usuwania komponentów, aby zapobiec wyciekom pamięci
- Usunąć nieużywane
import - Używać w pętlach
ngForfunkcjitrackBy - Pozbyć się niepotrzebnych zależności (przyda się
webpack-bundle-analyzer)