ANGULAR w mniej niż 40 minut

Page 1

ANGULAR w mniej niż 40 minut DARIUSZ KALBARCZYK NG-POLAND


ANGULAR W MNIEJ NIÅ» 40 MINUT DARIUASZ KALBARCZYK


Kim jestem?

www.helion.pl/autorzy/dariusz-kalbarczyk

3

@ngKalbarczyk


#ngPolandConf

4

@ngKalbarczyk


Angular Warsaw

www.meetup.com/Angular-Warsaw

5

@ngKalbarczyk


Czym jest Angular? PLATFORMA do tworzenia aplikacji SPA JEDEN FRAMEWORK Aplikacje WEBOWE Aplikacje MOBILNE Tworzenie aplikacji za pomocÄ… HTML, CSS oraz TYPESCRIPT

6

@ngKalbarczyk


Single page application

ANGULAR pomaga nam tworzyć aplikacje SPA Interakcja odbywa się bez przeładowania strony Komunikacja z serwerem poprzez REST-ful API

7

@ngKalbarczyk


AngularJS vs Angular

? 8

@ngKalbarczyk


angular.io

9

@ngKalbarczyk


Dlaczego Angular? Jeden framework dla web, mobile i desktop Modułowość

Performans

Niesamowite narzędzia: TypeScript, NativeScript, VSC

Wykorzystywany przez miliony

10

@ngKalbarczyk


Od czego zacząć?

Visual Studio Code Nodejs Angular CLI

11

@ngKalbarczyk


Visual Studio Code

12

@ngKalbarczyk


Snippets

13

@ngKalbarczyk


nodejs.org node -v npm -v

14

@ngKalbarczyk


cli.angular.io

15

@ngKalbarczyk


typescriptlang.org

16

@ngKalbarczyk


nativescript.org

Sebastian Witalec @sebawita

17

@ngKalbarczyk


TypeScript

18

@ngKalbarczyk


Konfiguracja IDE tsconfig.json { "compileOnSave": false, "compilerOptions": { "outDir": "./dist/out-tsc", "sourceMap": true, "declaration": false, "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, "target": "es5", "typeRoots": [ "node_modules/@types" ], "lib": [ "es2017", "dom" ‌

19

@ngKalbarczyk


ZACZYNAMY ZABAWĘ


Interpolation {{ value }}

<li>Name: {{ user.name }}</li> <li>Email: {{ user.email }}</li>

21

@ngKalbarczyk


Property Binding [property]="value" <input type="email" [value]="user.email"> <div [style.background-color]="selectedColor"> <div [class.selected]="isSelected">

22

@ngKalbarczyk


Two-Way Data Binding [(ngModel)]="value"

<p>{{name}}</p> <input type="text" [(ngModel)]="name">

23

@ngKalbarczyk


Event Binding (event)="function"

<button

(click)="getPosts()">Pobierz dane z serwera</button>

click / change / keyup / ‌

24

@ngKalbarczyk


FORMULARZE <form #newUserForm="ngForm" (ngSubmit)="onSubmit(newUserForm)">

import { NgForm } from '@angular/forms'; onSubmit(form: NgForm) { if (form.valid) { console.log(form.value); // formularz został poprawnie zweryfikowany } }

25

@ngKalbarczyk


WALIDACJA <input type="text" placeholder="Miasto" required maxlength="15" [(ngModel)]="city" name="city"

#pickedCity="ngModel"> <div *ngIf="!pickedCity.valid && pickedCity.touched"> Miasto jest wymagane! </div> <button type="submit" [disabled]="!newUserForm.form.valid"> Wyślij </button> <button type="button" (click)="newUserForm.reset()"> Wyczyść </button>

26

@ngKalbarczyk


ARCHITEKTURA

27

@ngKalbarczyk


MODUŁY import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component';

@NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule ], providers: [],

bootstrap: [AppComponent] })

}

Dekorator

Metadane

Moduł główny

export class AppModule { }

28

@ngKalbarczyk


METADANE

Mówią ANGULAROWI jak przetwarzać klasę

29

@ngKalbarczyk


KOMPONENTY DODANIE KOMPONENTU

REJESTRACJA W MODULE

DODANIE SZABLONU

30

@ngKalbarczyk


KOMPONENTY import { Component } from '@angular/core'; @Component({ Dekorator selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app'; Metadane }

31

@ngKalbarczyk


SELECTOR import { Component } from '@angular/core'; <app-root></app-root>

@Component({

selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app'; }

32

@ngKalbarczyk


SZABLON import { Component } from '@angular/core'; Szablon

@Component({ selector: 'app-root',

templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app'; }

33

@ngKalbarczyk


TABLICA STYLI import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html',

styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app'; }

34

@ngKalbarczyk


KLASA KOMPONENTU import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] })

export class AppComponent { title = 'WDI App'; Klasa zawierajÄ…ca } logikÄ™

35

@ngKalbarczyk


LIFECYCLE HOOKS HOOK

ngOnChanges()

ngOnInit()

ngOnDestroy()

CEL I CZAS

Wywoływana przed ngOnInit () i za każdym razem, gdy zmienia się jedna lub więcej właściwości wejściowych związanych z danymi.

Inicjuje dyrektywę / komponent.

Wywoływana raz, po pierwszym ngOnChanges().

Wywoływana zanim Angular zniszczy dyrektywę lub komponent.

36

@ngKalbarczyk


DYREKTYWY WBUDOWANE NgIf

NgClass

NgStyle NgForOf

NgSwitch NgSwitchCase

NgTemplateOutlet

NgSwitchDefault

37

@ngKalbarczyk


NgForOf <li *ngFor="let person of people"> {{ person.name }} </li> class ExampleComponent { people: any[ ] = [ { "name": „Angelika" }, { "name": "Oskar" },

38

@ngKalbarczyk


NgIf @Component({ selector: 'wdi', template: ` <button (click)="show = !show">{{show ? 'Ukryj' : 'Pokaż'}}</button> <div *ngIf="show">Text do wyświetlenia</div> ` }) class WdiComponent { show: boolean = true; }

39

@ngKalbarczyk


NgStyle [ngStyle]="{'font-style': styleExp}"

[ngStyle]="{'max-width.px': widthExp}"

[ngStyle]="objExp" <div [ngStyle]="{'background-color':'green'}"></<div>

[ngStyle]=„{‚background-color' : person.country === 'PL' ? ‚red' : 'black' }"

40

@ngKalbarczyk


PIPE DeprecatedDatePipe

AsyncPipe

DeprecatedCurrencyPipe

DeprecatedDecimalPipe

JsonPipe

DeprecatedPercentPipe

CurrencyPipe PercentPipe

LowerCasePipe

SlicePipe

TitleCasePipe

DatePipe

UpperCasePipe DecimalPipe

41

@ngKalbarczyk


DatePipe <!--output 'Jun 15, 2018'-->

<p>{{today | date}}</p>

<!--output 'Monday, June 15, 2018'-->

<p>{{today | date:'fullDate'}}</p>

<!--output '9:43 AM'-->

<p>{{today | date:'shortTime'}}</p>

<!--output 'Monday, June 15, 2015 at 9:03:01 AM GMT+01:00' -->

<p>The full date/time is {{today | date:'full'}}</p>

<!--output 'Lundi 15 Juin 2015 à 09:03:01 GMT+01:00'-->

<p>Pełna data po francusku: {{today | date:'full':'':'fr'}}</p>

<!--output '2015-06-15 05:03 PM GMT+9'-->

<p>Spersonalizowana data: {{today | date:'yyyy-MM-dd HH:mm a z':'+0900'}}</p>

42

@ngKalbarczyk


JsonPipe @Component({

selector: 'wdi-json-pipe',

template: `<div>

{{data | json}}

<pre> </pre>

</div>`

})

export class WdiJsonPipeComponent {

data: Object = {name: 'WDI', name: 'ngPoland', nested: {type: 1, numbers: [1,3,]}};

}

43

@ngKalbarczyk


AsyncPipe @Component({

selector: 'wdi-async-observable-pipe',

template: ‚<div>Czas: {{ time | async }}</div>'

})

export class WdiAsyncObservablePipeComponent {

time = new Observable<string>((observer: Subscriber<string>) => {

setInterval(() => observer.next(new Date().toString()), 1000);

});

}

44

@ngKalbarczyk


NAWIGACJA

import { RouterModule, Routes } from '@angular/router';

45

@ngKalbarczyk


NAWIGACJA const appRoutes: Routes = [

{ path: 'home', component: HomeComponent },

{ path: 'post/:id', component: PostDetailComponent },

{

path: 'blog',

component: BlogListComponent,

data: { title: 'Blog List' }

},

{ path: '**', component: PageNotFoundComponent }

];

46

@ngKalbarczyk


NAWIGACJA <nav>

<a routerLink="/home" routerLinkActive="class1 class2">Home</a> <a routerLink="/blog" routerLinkActive="class1 class2">Blog</a>

</nav>

<div>….</div>

<router-outlet></router-outlet> <div>….</div>

47

@ngKalbarczyk


KOMUNIKACJA GET 200 OK Klient

Serwer

4xx Error 5xx Error

48

@ngKalbarczyk


KOMUNIKACJA

POST { "name":"WDI" } Klient

Serwer

201 Created

49

@ngKalbarczyk


KOMUNIKACJA

GET / POST/ PUT / PATCH / DELETE

50

@ngKalbarczyk


HTTP - app.module.ts import { NgModule } from '@angular/core';

import { BrowserModule } from '@angular/platform-browser';

import { HttpClientModule } from '@angular/common/http';

@NgModule({

imports: [

BrowserModule,

// import HttpClientModule after BrowserModule.

HttpClientModule,

],

declarations: [

AppComponent,

],

bootstrap: [ AppComponent ]

})

export class AppModule {}

51

@ngKalbarczyk


HTTP - app.component.ts import { Component } from '@angular/core';

import { HttpClient } from '@angular/common/http';

@Component({

selector: 'app-root',

templateUrl: './app.component.html',

styleUrls: ['./app.component.css']

})

export class AppComponent {

readonly ROOT_URL = 'https://jsonplaceholder.typicode.com/';

posts: any;

constructor(private http: HttpClient) {

}

getPosts() { this.posts = this.http.get(this.ROOT_URL + 'posts'); } }

52

@ngKalbarczyk


HTTP - app.component.ts

<button (click)="getPosts()">Pobierz dane z serwera</button>

<div *ngFor="let post of posts | async">{{post | json}}</div>

53

@ngKalbarczyk


WIDOK

54

@ngKalbarczyk


INTERFEJS export interface Post { id: number; userId: number; title: string; body: string; }

55

@ngKalbarczyk


Observable import { Post } from './post'; import { Observable } from 'rxjs/Observable'; . . posts: Observable<Post[ ]>; constructor(private http: HttpClient) {} getPosts() { this.posts = this.http.get<Post[

]>(this.ROOT_URL + 'posts');

} }

56

@ngKalbarczyk


HttpParams import { HttpClient, HttpParams } from '@angular/common/http'; . . . getPosts() { const params = new HttpParams().set('userId', '1'); this.posts = this.http.get(this.ROOT_URL + 'posts', {params}); }

57

@ngKalbarczyk


WIDOK

58

@ngKalbarczyk


HttpHeaders

const headers = new HttpHeaders().set('Authorization', 'auth-token'); this.posts = this.http.get(this.ROOT_URL + 'posts', { headers });

59

@ngKalbarczyk


WIDOK

60

@ngKalbarczyk


RAZEM getPosts() {

HttpParams().set('userId', '1'); let headers = new HttpHeaders().set('Authorization', 'auth-token'); let params = new

this.posts = this.http.get(this.ROOT_URL + '/posts', { params, headers }) }

61

@ngKalbarczyk


POST createPost() { const data: Post = { id: null, userId: 88, title: 'To jest tytuł', body: 'To jest body' }; this.newPost = this.http.post(this.ROOT_URL + 'posts', data); } <button (click)="createPost()">Dodaj wpis</button> {{ newPost | async | json }}

62

@ngKalbarczyk


RxJS import 'rxjs/add/operator/catch'; import 'rxjs/add/operator/retry'; import ‚rxjs/add/observable/of'; . . . this.newPost = this.http.post(this.ROOT_URL + '-posts', data) .retry(3) .catch(err => { console.log(err); return Observable.of(err); });

63

@ngKalbarczyk


WIDOK

64

@ngKalbarczyk


SERWIS import { Injectable } from '@angular/core';

@Injectable() export class PostsService { … getPosts(): Observable<any> {...} createPost() {...}

65

@ngKalbarczyk


KOMPONENT import { PostsService } from './posts.service';

constructor(private postsService: PostsService) { }

getPosts() { this.posts = this.postsService.getPosts(); } createPost() { this.newPost = this.postsService.createPost(); }

66

@ngKalbarczyk


Gdzie szukać wiedzy?

ULTIMATE ANGULAR

Angular.Love

ANGULAR Warsaw GDG Warszawa

codewithstyle

67

@ngKalbarczyk


Gdzie szukać inspiracji?

@jsPolandConf

68

@ngKalbarczyk


DZIĘKUJĘ ngKalbarczyk ngKalbarczyk dKalbarczyk darek@ngpoland.pl

69

@ngKalbarczyk


>>>Pytania? Zadawaj je, oceniaj prelekcjÄ™, komentuj lub polub poprzez sli.do:

WarszawskieDniInformatyki.pl/slido


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.