Tak jak obiecałam, choć dużo później niż początkowo zakładałam – bierzemy się za kod.
W dzisiejszym artykule omówimy kod przykładowej aplikacji wygenerowanej z wykorzystaniem Angular CLI. Stukturę katalogów wygenerowanego projektu omawiałam już jak coś w jednym z poprzednich artykułów, dziś skupimy się na zawartości folderu src.
Wymagania wstępne:
Spisane w formie checklisty (do wydrukowania bądź podglądu/importu jako szablon Nozbe):
Szablon Nozbe do podglądu i pobrania
No i przede wszystkim: wygenerowany z Angular CLI projekt, który będziemy omawiać. Choć tutaj możesz też działać w oparciu o kod umieszczony tutaj.
Materiały do nauki oraz informacje co i jak znajdziesz we wpisie Tworzymy aplikację webową – krok po kroku – podsumowanie aktualnego statusu & co dalej?
Branch, odpowiadający dzisiejszemu artykułowi: https://github.com/nettecode/todoSampleWebApp/tree/angularCliApp
Czym będzie ta część serii tutorialowej?
Chciałabym przedstawić proces myślowy towarzyszący tworzeniu prostej aplikacji To do. To nie będzie omawianie krok po kroku kodu gotowej aplikacji, a jej rozwijanie. Oznacza to, że kod, który zobaczycie po drodze nie będzie kodem idealnym, będziemy go poprawiać, aż dojdziemy do efektu, który chcemy uzyskać. Jeśli ktoś ma zastrzeżenia do kodu – warto by najpierw zajrzał do kodu skończonej aplikacji i sprawdził, czy błąd nadal występuje. Jeśli nie – zapewne będzie tematem jednego z artykułów, w którym go poprawimy/rozwiniemy.
Demo aplikacji docelowej (jeszcze bez dodawania nowych zadań na listę oraz podłączonego Bootstrapa): TUTAJ
Wiem, że nie zwala z nóg. Nawet z podłączonym Bootstrapem czy możliwością dodawania zadań nie będzie tego robić. Bo to nie jej zadanie. Jej zadaniem będzie uczyć podstaw. W najprostszy możliwy sposób. Wrażenie może robić np. inna aplikacja, którą buduję w oparciu o ten sam stos technologiczny – Meals Planner (z tym, że ma np. Angular Material zamiast Bootstrapa). Wrażenie będą mogły robić Wasze projekty 😉
Wiem też jednocześnie, że to raczej ostatni sezon, który będzie w formie opisowej. Następny robię już raczej w formie video. Pisanie tej serii… zajęło masakrycznie dużo czasu. Myślę, że dużo przystępniejszy byłby tutorial w formie video. Być może ten również przedstawię w takiej formie 😉
Jak wygląda nasza aplikacja początkowa?
Dość skromnie, prawda? Idealnie na start 🙂
Nie opisuję jak ją wygenerować. O tym już pisałam szczegółowo tutaj.
Jeśli chodzi o uruchomienie, wprowadź w linii komend:
ng serve
Aplikacja (domyślnie) zostanie uruchomiona pod adresem: http://localhost:4200/
O tym już również pisałam we wspomnianym artykule.
W artykule nt. Angular CLI omówiłam całą strukturę katalogów projektu. Ale wspomniałam, że do najważniejszego z nich jeszcze dojdziemy. To dziś 😉
Chodzi o folder src/app. To tu znajduje się nasza aplikacja. Reszta dotyczy tak naprawdę jej konfiguracji, dodatkowych narzędzi przydatnych w development’cie i nie tylko.
W folderze widzimy następujące pliki:
- component.html
- component.scss (albo .css, jeśli do generowania projektu nie wykorzystano –style=scss)
- component.spec.ts
- component.ts
- module.ts
Omawianie zaczniemy od najważniejszego z nich:
AppModule
Każda aplikacja Angularowa ma przynajmniej jeden moduł „główny” (root module). Zwyczajowo nazywany jest AppModule.
Aplikacje Angularowe bazują na modułach i mają swój własny system modułów (modularity system) nazywany NgModules.
Jak wygląda jego zawartość?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } |
Najważniejszą jego część stanowi decorator @NgModule.
Dekoratory to funkcje modyfikujące klasy JavaScriptowe, dodają dodatkowe informacje o klasach (tzw. metadane).
Angular korzysta z wielu dekoratorów.
W naszym przypadku dekorator @NgModule określa:
- declarations
- imports
- providers
- bootstrap
Zaczynając od końca:
Bootstrap wskazuje główny komponent aplikacji, który jest wstawiany w index.html. Domyślasz się, w którym miejscu?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>TodoSampleWebApp</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> </head> <body> <app-root></app-root> </body> </html> |
Tak, <app-root>.
Co zostanie umieszczone w przypadku naszej aplikacji?
AppComponent, czyli zawartość pliku app.component.html (do której jeszcze dojdziemy). AppComponent jest też domyślną nazwą dla głównego komponentu aplikacji.
Oczywiście w tablicy [] może zostać umieszczone więcej komponentów niż jeden.
Aaa! O ile możemy użyć więcej niż jednego dekoratora @NgModule, własność bootstrap powinna być ustawiana tylko w module głównym.
Declarations – tablica zawierająca wszystkie klasy odpowiadające za widok (view classes), należące do aplikacji: komponenty, dyrektywy i pipes (czy ktoś zna tłumaczenie „pipes” na polski? modyfikatory?).
I tak. Jeśli tworzysz nowy komponent – musisz dodać jego nazwę do tablicy deklaracji w AppModule. Jeśli skorzystasz w tym celu z Angular CLI – zrobi on to za Ciebie.
Providers zawiera listę wszystkich serwisów, z jakich chcemy skorzystać, tworzy ich instancje.
Zakres „widoczności” takiego serwisu jest zależny od miejsca, w którym go umieścimy.
Jeśli umieścimy je na liście providers dla NgModule modułu głównego aplikacji – instancja serwisu będzie dostępna w całej aplikacji.
Jeśli umieszczamy providers dla danego komponentu – tworzymy oddzielną instancję serwisu dla danego komponentu.
Dlaczego to jest istotne? Ponieważ jeśli umieścisz serwis oddzielnie w wielu różnych komponentach – będą to oddzielne instancje serwisu. Oznacza to tyle, że jeśli będziesz na nich działać – działasz na różnych obiektach. A zatem, zmieniając stan w serwisie A, nie zmienisz stanu w serwisie B. Jeśli chcesz by komponenty komunikowały się ze sobą z wykorzystaniem serwisu – nie tędy droga.
Imports określa jakich modułów potrzebuje aplikacja do swojego działania.
1 2 3 |
imports: [ BrowserModule ], |
I tak np. widzimy, że nasza aplikacja do swojego działania potrzebuje BrowserModule.
BrowserModule jest modułem wykorzystywanym przez każdą aplikację angularową, która musi wykonywać się w przeglądarce. Angular CLI załącza go domyślnie do aplikacji początkowej.
Tablica Imports to jedno, ale na samym początku naszego pliku app.module.ts widzimy również:
1 2 3 4 |
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; |
Otóż każdy component, provider, itd. wykorzystywany w @NgModule musi być zaimportowany. Nie można wrzucić do koszyka czegoś, czego nie mamy. Musimy to najpierw dostać.
Dobrym nawykiem jest import angularowych bibliotek (@angular/cośtam) przed komponentami naszej aplikacji. I np. linijka odstępu pomiędzy.
import będziemy wykorzystywać w każdej klasie aplikacji, która będzie potrzebowała innej klasy. Import nie jest czymś wprowadzanym przez aplikacje angularowe i mam nadzieję, że na tym etapie nie muszę tego tłumaczyć w szczegółach. Jeśli jednak potrzebujesz informacji na ten temat szukaj pod hasłem Javascript modules, ew. zajrzyj tutaj.
W naszej aplikacji pojawia się również słówko export:
1 |
export class AppModule { } |
To dzięki temu możemy wykorzystać daną klasę, mamy do niej dostęp, możemy ją zaimportować w kolejnych klasach.
A skąd aplikacja ma wiedzieć, który moduł uruchomić? Plik main.ts:
1 2 3 4 5 6 7 8 9 10 11 12 |
import { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; if (environment.production) { enableProdMode(); } platformBrowserDynamic().bootstrapModule(AppModule) .catch(err => console.log(err)); |
Podsumowanie
Omówiliśmy główny moduł aplikacji, elementy, które określa. Za tydzień weźmiemy się za tworzenie naszego pierwszego komponentu i omówimy kwestie z tym związane.
Wiem, że artykuł nie jest zbyt prosty i dla części z Was zawiera wiele nieznanych pojęć. Początkowo bardzo się rozpisywałam. Nie jest to jednak kurs Angular’a. To jest tutorial tworzenia aplikacji webowej. Jeśli potrzebujecie zgłębić temat Angular v4 podawałam miejsca, w których to zrobić. Po każdym artykule będę również umieszczać listę linków z materiałami dodatkowymi.
Jeśli coś jest dla Was niezrozumiałe – dawajcie znać w komentarzach lub na tutorialowej grupie wsparcia. Wytłumaczę 🙂 Wydaje mi się, że to jeden z cięższych artykułów, dalej będzie łatwiej 😉
Więcej…
Architecture Overview https://angular.io/guide/architecture
Bootstraping https://angular.io/guide/bootstrapping
NgModules https://angular.io/guide/ngmodule
Lektura dodatkowa:
A deep dive on Angular decorators https://toddmotto.com/angular-decorators#class-decorators
JavaScript Modules (exploringjs) http://exploringjs.com/es6/ch_modules.html
Ciąg dalszy za tydzień…