Modern
& applicative

(Part 3)

getting started
What is angular?
Single-page applications
Web framework
developed by Google
for building
advantages of spa over mpa
Performance
Loose coupling from server
Debugging
component-driven development
"Component is an independent piece of UI"

components - features
Reusability
Modularity
Easy to test
?
components <=> functions
function createPerson(name, age) { return { name, age }; } createPerson('Kajetan', 26);
<h1>Kajetan</h1> <p>26</p>
input
output
<person-card name="Kajetan" age="26" ></person-card>
{ name: 'Kajetan', age: 26 }
function
component
let's talk about angular!
angular architecture

angular cli
Initialize your app
Generate elements
Maintain
>> ng new splitter
>> ng g c action-card
>> ng update @angular/core
Run dev env
>> ng serve
project structure
>> ng g c action-card
creating component
component's lifecycle hooks
ngOnInit | Called once the component is initialized |
ngOnChanges | Called after bound input propoerty changes |
ngAfterContentInit | Called after content of component has been projected into view |
ngAfterViewInit | Called after component's view has been initialized |
ngOnDestroy | Called once the component is about to be destroyed |
>> ng g c action-list
creating component
property binding
@Component({ selector: 'app-action-card', template: ` <h3>{{ action.description }}</h3> ` }) export class ActionCardComponent { @Input() action: Action; } @Component({ selector: 'app-action-list', template: ` <app-action-card [action]="actions[0]"></app-action-card> ` }) export class ActionListComponent { actions: [{ ... }]; }
@Component({ selector: 'app-action-card', template: ` <h3>{{ action.description }}</h3> ` }) export class ActionCardComponent { @Input() action: Action; } @Component({ selector: 'app-action-list', template: ` <app-action-card [action]="actions[0]"></app-action-card> ` }) export class ActionListComponent { actions: [{ ... }]; }
@Component({ selector: 'app-action-card', template: ` <h3>{{ action.description }}</h3> ` }) export class ActionCardComponent { @Input() action: Action; } @Component({ selector: 'app-action-list', template: ` <app-action-card [action]="actions[0]"></app-action-card> ` }) export class ActionListComponent { actions: [{ ... }]; }
@Component({ selector: 'app-action-card', template: ` <h3>{{ action.description }}</h3> ` }) export class ActionCardComponent { @Input() action: Action; } @Component({ selector: 'app-action-list', template: ` <app-action-card [action]="actions[0]"></app-action-card> ` }) export class ActionListComponent { actions: [{ ... }]; }
structural directives
@Component({ selector: 'app-action-card', template: ` <app-action-card *ngFor="let action of actions" [action]="action" ></app-action-card> <div *ngIf="actionSaved" class="alert alert-success"> Actions saved successfully! </div> <button (click)="actionsSaved = true">Save All</button> ` }) export class ActionListComponent { actions: Action[] = []; actionsSaved = false; (...) }
@Component({ selector: 'app-action-card', template: ` <app-action-card *ngFor="let action of actions" [action]="action" ></app-action-card> <div *ngIf="actionSaved" class="alert alert-success"> Actions saved successfully! </div> <button (click)="actionsSaved = true">Save All</button> ` }) export class ActionListComponent { actions: Action[] = []; actionsSaved = false; (...) }
@Component({ selector: 'app-action-card', template: ` <app-action-card *ngFor="let action of actions" [action]="action" ></app-action-card> <div *ngIf="actionSaved" class="alert alert-success"> Actions saved successfully! </div> <button (click)="actionsSaved = true">Save All</button> ` }) export class ActionListComponent { actions: Action[] = []; actionsSaved = false; (...) }
services
Fetching remote data
Validation
Data processing
(Provided with Dependency Injection)
dependency injection
@Component({ selector: 'app-action-card', template: ` <app-action-card *ngFor="let action of actions" [action]="action" ></app-action-card> ` }) export class ActionListComponent { actions: Action[] = []; constructor( private actionService: ActionService ) {} (...) }
@Component({ selector: 'app-action-card', template: ` <app-action-card *ngFor="let action of actions" [action]="action" ></app-action-card> ` }) export class ActionListComponent { actions: Action[] = []; constructor( private actionService: ActionService ) {} (...) }
@Injectable() export class ActionService { constructor(private http: HttpClient) {} getAllActions() { ... } }
rxJs
("asynchronous data streams", "Promises on steroids")

>> ng g c user-create
creating component
ROUTING & NAVIGATION
const routes: Routes = [ { path: 'action-list', component: ActionListComponent }, ... ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
<nav> <a routerLink="/action-list">Action List</a> </nav> <router-outlet></router-outlet>
app-routing.module.ts
app.component.html
(lazy loading is also possible...)
<nav class="navbar navbar-dark justify-content-start bg-dark"> <h1 class="navbar-brand mb-0 mr-3"> Splitter </h1> <a class="nav-item nav-link text-white" routerLink="/action-list"> Action List </a> <a class="nav-item nav-link text-white" routerLink="/user-create"> Create User </a> </nav>
template-driven forms
<form #userForm="ngForm" (ngSubmit)="createUser()"> <div class="form-group"> <label for="name">Name</label> <input id="name" class="form-control" type="text" [(ngModel)]="model.name" name="name" > </div> (...) <button type="submit" class="btn btn-success"> Submit </button> </form>
@Component({}) export class UserCreateComponent { model: User = { id: '', email: '', name: '', password: '' }; createUser() { saveToDb(this.model); } }
user-create.component.html
user-create.component.ts
why angular?
"Imposed" architecture
Ready, solid solutions
Google's and community's suppport
Modern & applicative (Part 3)
Getting started with Angular
By Kajetan Świątek
Getting started with Angular
- 336