Kolejna odsłona artykułu z serii Tips & Tricks! Standardowo bez zbędnego lania wody, lecimy!
1. TOKEN APP_INITIALIZER
Angular umożliwia nam uruchomienie dowolnej funkcji podczas inicjalizacji aplikacji, dzięki temu możemy wywołać dany kod przed zrenderowaniem czegokolwiek. Link do dokumentacji:
APP_INITIALIZER
Jak widzimy w dokumentacji:
“A function that will be executed when an application is initialized.”
LIVE EXAMPLE (w pliku app.module.ts)
Bardzo przydatne, jak np. chcemy załadować jakąś konfigurację lub wykonać call HTTP jeszcze przed załadowaniem aplikacji.
2. ExportAs
Zaglądając do dokumentacji @Directive, trafiamy na opcjonalną propercję exportAs. Można ją bardzo prosto wytłumaczyć:
ExportAs pozwala nam uzyskać dostęp do konkretnej instancji dyrektywy.
Zapewne nieraz już sięgałeś do instancji komponentu, w następujący sposób:
1 2 3 |
<sidebar></sidebar> <- w templatce ... @ViewChild(SideBarComponent) sidebar; <- w klasie |
W ten oto prosty sposób za pomocą dekoratora @ViewChild, otrzymujemy dostęp do instancji konkretnego komponentu na widoku, w tym przypadku SidebarComponent (można również wspomóc się template-variable (#))
Nałóżmy teraz na nasz komponent dyrektywę o selektorze “someDirective”:
1 |
<sidebar someDirective></sidebar> |
Która prezentuje się następująco:
1 2 3 4 5 6 7 |
@Directive({ selector: '[someDirective]', exportAs: 'someDirective' }) class MySomeDirective { public someMethod() {} } |
Dzięki użyciu exportAs możemy już uzyskać dostęp do konkretnej instancji dyrektywy przypisując ją do template variable (#):
1 |
<sidebar #someDirectiveRef="someDirective"></sidebar> |
…i sięgać teraz do jej metod publicznych, uprzednio łapiąć do niej referencję poprzez @ViewChild:
1 2 3 |
@ViewChild('someDirectiveRef') someDirective; ... this.someDirective.someMethod(); |
lub bezpośrednio w templatce, bez użycia ViewChild:
1 |
<div (mouseover)="someDirectiveRef.someMethod()">...</div> |
ExportAs jest przydatny zawsze, kiedy chcemy umożliwić dostęp do API dyrektywy.
3. Dekorator @Attribute
Niezbyt popularny dekorator.
DOKUMENTACJA @ATTRIBUTE
Mogliby w dokumentacji go nieco lepiej opisać.
Czemu służy? Przykładowo, mamy komponent:
1 |
<hello-world id="my-hello-world-component"></hello-world> |
Dekorator @Attribute, pozwala nam uzyskać dostęp do atrybutu hosta, czyli z poziomu klasy HelloWorldComponent, możemy odczytać nałożony na niego ID (lub jakikolwiek inny atrybut). Aby uzyskać dostęp do atrybutu hosta, wstrzykujemy dekorator do konstruktora elementu:
1 2 3 4 5 |
export class HelloComponent { constructor(@Attribute('id') public hostId: string) { console.log('hostId', hostId); // "my-hello-world-component" } } |
A do parametru dekoratora, przekazujemy nazwę atrybutu, jaki chcemy odczytać (id, class etc). Oczywiście, może być również wykorzystany w dyrektywie.
LIVE EXAMPLE (HelloWorldComponent)
4. Automatyczna rejestracja usługi w Module.providers
Za pomocą Angular CLI, możemy szybko stworzyć serwis:
1 |
ng g service path/myService |
Powyższa komenda utworzy nam serwis we wskazanym miejscu i doda do nazwy pliku suffix .service.
Niestety dodany serwis, nie zostaje zarejestrowany w żadnym module. Jednak z pomocą odpowiedniej flagi (–module=NAZWA_MODUŁU), możemy to zrobić automatycznie:
1 |
ng g service myService --module=SOME_MODULE_NAME |
W ten oto sposób, nasz serwis MyService został automatycznie dodany do tablicy Providers w SomeModule.
5. Observable.merge & valueChanges in Reactive Forms
W Reactive Forms, możemy nasłuchiwać na zmiany, które odbiera kontrolka:
1 |
const usernameCtrl$ = this.form.get('username').valueChanges; |
1 2 3 4 5 |
const usernameCtrl$ = this.form.get('username').valueChanges; const passwordCtrl$ = this.form.get('password').valueChanges; Observable.merge(usernameCtrl$, passwordCtrl$) .subscribe(() => ...some custom action); |
Przykład:
6. StylePreporcessorOptions w .angular-cli.json
Założmy, że w katalogu assets, stworzyliśmy folder styles. Trzymamy tam np. plik variables.scss.
W tym momencie, gdy sięgamy po plik variables.scss w stylach naszych komponentów, nasze ścieżki mogą wyglądać następująco:
1 |
@import '../../../assets/styles/variables'; |
Czyż nie byłoby lepiej, gdyby wystarczyło wpisać:
1 |
@import 'variables'; |
…niezależnie, w jakim pliku jesteśmy względem pliku variables.scss? No pewnie, że tak 😉
W tym celu, przechodzimy do pliku .angular-cli.json i dodajemy stylePreprocessorOptions:
1 2 3 4 5 6 7 8 9 |
"apps": [ { "root": "src", "stylePreprocessorOptions": { "includePaths": [ "assets/styles" ], ... }, |
7. Globalna obsługa errorów Routingu
Angular umożliwia nam globalną obsługę errorów związanych routingiem. Robimy to w następujących krokach:
- Piszemy naszą klasę, która implementuje ErrorHandler:
1 2 3 4 5 |
export class CustomErrorHandler implements ErrorHandler { handleError(error) { // TUTAJ NASZ KOD - np. pokazanie toasta } } |
2. Następnie w app.module.ts rejestrujemy provider:
1 2 3 |
providers: [ { provide: ErrorHandler, useClass: CustomErrorHandler} ], |
I vuala, możemy się cieszyć wywołaniem naszego kodu podczas errorów związanych z routingiem.
Tak jak dotychczas, 7 tipów. Mam nadzieję, że chociaż jeden był dla Ciebie nowy 🙂
Dobra robota!
Pingback: Angular Tips & Tricks cz. VI - Angular.love