Wykład 5: Tworzenie aplikacji SPA w Angularze
mgr inż. Maciej Małecki
Node
- środowisko uruchomieniowe dla JavaScriptNPM
- ang. Node Package Manager - zarządzanie zależnościamiNPM registry
- repozytorium bibliotekTypeScript
- podstawowy język programowania dla Angular 2.x+Angular CLI
- narzędzie linii poleceń wspierające proces tworzenia i budowaniaKarma, Jasmine, JEST, Protractor, Cypress
- środowisko tworzenia testówInstalacja node ⇝ nvm
Instalacja Angular CLI
npm install -g @angular/cli
Wygenerowanie aplikacji Angular
$ ng new
? What name would you like to use for the new workspace and initial project? foo
? Do you want to enforce stricter type checking and stricter bundle budgets in the workspace?
This setting helps improve maintainability and catch bugs ahead of time.
For more information, see https://angular.io/strict Yes
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? SCSS [ https://sass-lang.com/documentation/syntax#scss ]
Zbudowanie aplikacji
ng build --prod
Uruchomienie aplikacji
ng serve -o
NgModule
)Moduł ECMA Script oraz Moduł Angulara to dwie różne rzeczy!
@NgModule({
imports: [CommonModule],
declarations: [
MyComponent1,
MyComponent2,
MyExternalComponent3
],
exports: [MyExternalComponent3]
})
export class MyModule {
}
@NgModule
- dekorator TypeScriptstandalone
.
ng generate component user-mgmt/user-list
html
- szablon - część wizualna, ang. template (opcja)scss
- prywatny arkusz styli (opcja)component.ts
- kod/kontroler komponentuspec.ts
- testy jednostkowe komponentu (opcja)Definicja wyglądu komponentu w HTML:
lub z użyciem zewnętrznego pliku:
user-list.component.html
DOM (Document Object Model) jest to model obiektowy reprezentujący dokument HTML wyświetlany przez przeglądarkę.
Przeglądarka buduje DOM w pamięci za każdym razem, gdy wyświetla HTML.
Każdy skrypt JavaScript (a więc także i każda aplikacja Angular) wchodzi w interakcję z DOM.
Postawowe API elementów DOM:
atrybut | dodatkowa wartość definiująca tag (w dokumencie HTML) |
właściwość | (property), właściwość obiektu DOM (zwykła właściwość obiektu w JS) |
metoda | funkcja obiektu DOM, którą można wywołać |
zdarzenie | (event) - informacja o zaistnieniu pewnego faktu, np click, focus, blur |
Data binding są to mechanizmy pozwalające na integrację modelu z widokiem.
{{interpolation}} |
wyliczy wyrażenie wewnątrz {{}} oraz wstawi wartość |
[property_binding] |
Angular będzie aktualizował wartość właściwości na podstawie wyrażenia |
(event_binding) |
wywołana zostanie funkcja w reakcji na zaistnienie zdarzenia |
[(two_way_binding)] |
synchronizuje model z widokiem "w obie strony" |
Detekcja zmian
Cykl życia komponentu
Dyrektywy to elementy rozszerzające funkcjonalność HTML, które można deklarować za pomocą Angular.
Istnieją trzy rodzaje dyrektyw:
ngModel
- wiążą pola edycyjne z modelemngClass
- pozwalają dynamicznie modyfikować klasy CSSngStyle
- pozwalają dynamicznie modyfikować style CSS
divClasses = {};
...
this.divClasses: {
'valid': this.isValid(),
'highlighted': this.isHighlighted()
}
W prostszych przypadkach...
*ngIf
- dodaje/usuwa element z
DOM:
*ngfor
- iteruje po liście i
dodaje element DOM dla każdego elementu listy:
ngSwitch, *ngSwitchCase,
*ngSwitchDefault
- odpowiednik instrukcji switch/case/default z innych języków
programowania.
Angular pozwala na stosowanie data bindings we własnych komponentach.
Dla danych wejściowych:
export class UserDetailsComponent
{
...
@Input() user: User;
...
}
Dla danych wyjściowych:
export class UserDetailsComponent
{
...
@Output() onChanged = new EventEmitter<User>();
...
this.onChanged.emit(user);
...
}
@Input({required=true})
@Input({transform: booleanAttribute})
Jak działa przeglądarka?
Router jest modułem Angulara, który implementuje podstawowe funkcje przeglądarki (URL, historia) w aplikacjach typu Single-Page.
router-outlet
określa miejsce, w którym Router będzie
"wklejał" nasz komponent.
Więcej informacji na https://angular.io/guide/router.
Serwis to współdzielony kod aplikacji:
@Injectable()
export class UserService {
users: User[] = [];
constructor() {
this.users = [
{id: 1, name: 'John Doe', email: 'john.doe@email.com'},
{id: 2, name: 'Max Rockatansky', email: 'mad.max@email.com'},
{id: 3, name: 'Chuck Peddle', email: 'chuck@mos.com'}
];
}
getAllUsers() {
return this.users;
}
saveUser(user: User) {
const found = this.findUser(user.id);
if (found) {
Object.assign(found, user);
} else {
this.users.push(user);
}
}
findUser(id: number) {
return this.users.find((user: User) => user.id === id);
}
getNextId() {
return this.users
.map((elem: User) => elem.id)
.reduce((prev, curr) => prev > curr ? prev : curr, 0) + 1;
}
}