DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek...
Transcript of DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek...
![Page 1: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/1.jpg)
DEVFEST 2016 -ANGULAR 2 WORKSHOP
Milan Lempera
Víťa Plšek
Matěj Horák
@milanlempera
@vitaplsek
@horakmat
angular.cz
![Page 2: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/2.jpg)
O nás
Milan Lempera
php, javascript, clojure(script)
@milanlempera
Víťa Plšek
java, javascript
@vitaplsek
angular.cz
0‐1
![Page 3: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/3.jpg)
O nás
Matěj Horák
java, javascript
@horakmat
Víťa Plšek
java, javascript
@vitaplsek
0‐2
![Page 5: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/5.jpg)
PART 1 1‐0
![Page 6: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/6.jpg)
Angular JS
Angular 1.Xsince 2009
Angular 2since 2016
1‐1
![Page 7: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/7.jpg)
1‐2
![Page 8: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/8.jpg)
1‐3
![Page 9: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/9.jpg)
JavaScript vs TypeScriptfunction area(r) { return Math.PI * r * r; } let myNumber = 2; let myString = '2' area(myNumber); // Ok area(myString); // Ok
function area(r: number): number { return Math.PI * r * r; } let myNumber = 2; let myString = '2' area(myNumber); // Ok area(myString); // ERROR
1‐4
![Page 10: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/10.jpg)
Arrow functionslet area = r => Math.PI * r * r;
let area = (r: number) => Math.PI * r * r;
1‐5
![Page 11: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/11.jpg)
TypeScriptlet myNumber = 2; // typ bude odvozen
let otherNumber:number = 2;
myNumber = 'someString'; // ERROR
otherNumber = 'someString'; // ERROR
// definice typů pole
let arrayOfNumbers: number[];
// generika
let numbers: Set<number> = new Set();
numbers.add(1); // OK
numbers.add("a"); // ERROR
1‐6
![Page 12: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/12.jpg)
TypeScript - Classclass Greeter { private message: string;
constructor(message: string) { this.message = message; }
greet() { return "Hello, " + this.message; }}
let greeter = new Greeter("world");
1‐7
![Page 13: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/13.jpg)
TypeScript - Classclass Greeter {
constructor(private message: string) { }
greet() { return "Hello, " + this.message; }}
let greeter = new Greeter("world");
1‐8
![Page 14: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/14.jpg)
TypeScript - Interfaceinterface Speaker { id?: number; name: string; }
"structural subtyping" / "duck typing"záleží jen na struktuře objektu
let speaker1: Speaker = { // OK id: 1, name: 'Petr Novák' };
let speaker2: Speaker = { // OK - id není povinné name: 'Petr', surname: 'Novák' };
let speaker3: Speaker = { // ERROR - neobsahuje name id: 11, surname: 'Novák' };
1‐9
![Page 15: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/15.jpg)
TypeScript - Dekorátoryfunction enableLogging(target) { target.loggingEnable = true; }
@enableLogging class Calculator { }
const calculator = new Calculator(); calculator.loggingEnable // true
můžete dekorovat i vlastnos� a metody
1‐10
![Page 16: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/16.jpg)
Struktura aplikaceAngular staví aplikaci jako strom komponent
app‐root
app‐task‐listapp‐task‐detailapp‐task‐infoapp‐task‐ac�ons
1‐11
![Page 17: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/17.jpg)
Angular CLIdevstack
scafolding
Vygenerování komponentyng generate component tasks/task-list
installing component create src/app/tasks/task-list/task-list.component.css create src/app/tasks/task-list/task-list.component.html create src/app/tasks/task-list/task-list.component.spec.ts create src/app/tasks/task-list/task-list.component.ts
1‐12
![Page 18: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/18.jpg)
Komponentaimport { Component, OnInit } from '@angular/core';
@Component({ selector: 'app-task-list', templateUrl: './task-list.component.html', styleUrls: ['./task-list.component.css'] }) export class TaskListComponent implements OnInit {
constructor() { }
ngOnInit() { }
}
Použití komponenty v šabloně<app-task-list></app-task-list>
1‐13
![Page 19: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/19.jpg)
Attributy a metody komponentyimport { Component, OnInit } from '@angular/core'; import { Task } from './task';
@Component({ selector: 'app-task-list', templateUrl: './task-list.component.html', styleUrls: ['./task-list.component.css'] }) export class TaskListComponent implements OnInit {
tasks: Task[]; selectedTask: Task;
getTotalEstimation() { return ... }
...
}
1‐14
![Page 20: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/20.jpg)
Šablona komponentyInterpolace
<h1>{{selectedTask.title}}</h1>
<span>Total Estimation: {{getTotalEstimation()}}</span>
Cykly, podmínky<ul> <li *ngFor="let task of tasks">
{{task.title}} <span *ngIf="task.isOverdue">Overdue !</span>
</li> </ul>
1‐15
![Page 21: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/21.jpg)
Event binding<button type="button" (click)="upVote(task)">Vote</button>
<span [class]="task.type"></span>
<input type="text" [(ngModel)]="task.title" />
Také u vlastních komponent<app-task-list [tasks]="overdueTasks" (onUpVote)="voteForTask($event)"> </app-task-list>
1‐16
![Page 22: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/22.jpg)
Rozhraní komponenty@Component({ selector: 'app-task-list', templateUrl: './task-list.component.html', styleUrls: ['./task-list.component.css'] }) export class TaskListComponent implements OnInit {
@Input() tasks: Task[]; @Output() onUpVote = new EventEmitter<Task>();
upVote(task) { this.onUpVote.emit(task); }
...}
<app-task-list [tasks]="overdueTasks" (onUpVote)="voteForTask($event)"> </app-task-list>
1‐17
![Page 23: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/23.jpg)
Vyzkoušejte si to 1‐18
![Page 24: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/24.jpg)
PART 2 2‐0
![Page 25: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/25.jpg)
ModulyModuly vystavují komponenty a udávají závislost na jiné moduly
@NgModule({ declarations: [ AppComponent, TaskDetailComponent, TaskListComponent, Error404Component ],
imports: [ BrowserModule, HttpModule, ],
bootstrap: [AppComponent] }) export class AppModule {}
2‐1
![Page 26: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/26.jpg)
Routingtransparentní chování aplikace v prostředí webu
stav a URL adresa jsou vzájemně provázané
historie (vpřed, zpět)možnost poslat/uložit URL
2‐2
![Page 27: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/27.jpg)
Router ModuleRouterModule.forRoot([ {path: '', component: TaskListComponent}, {path: 'task/:id', component: TaskDetailComponent}, {path: '**', component: Error404Component} ] )
Vykreslení v šabloně<html> <head> </head> <body>
<router-outlet></router-outlet>
</body> </html>
2‐3
![Page 28: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/28.jpg)
Moduly a routing@NgModule({ imports: [ RouterModule.forRoot([ {path: '', component: TaskListComponent}, {path: 'task/:id', component: TaskDetailComponent}, {path: '**', component: Error404Component} ] ) ], exports: [ RouterModule ] }) export class AppRoutingModule {}
2‐4
![Page 29: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/29.jpg)
Moduly a routing@NgModule({ declarations: [ AppComponent, TaskDetailComponent, TaskListComponent, Error404Component ],
imports: [ BrowserModule, HttpModule, AppRoutingModule // routing modul ],
bootstrap: [AppComponent] }) export class AppModule {}
2‐5
![Page 30: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/30.jpg)
Přechod mezi routami<a routerLink="/tasks">Seznam</a>
<a [routerLink]="['task', task.id]">Detail</a>
2‐6
![Page 31: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/31.jpg)
Injectablesimport { Task } from "./task";import { Injectable } from "@angular/core";
@Injectable() export class TaskDataService {
getTasks(): Task[]{ ... }
}
2‐7
![Page 32: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/32.jpg)
Začlenení do modulu@NgModule({ declarations: [ AppComponent, TaskDetailComponent, TaskListComponent, Error404Component ],
imports: [ BrowserModule, HttpModule, AppRoutingModule ],
providers: [TaskDataService], // injektovatelná závislost
bootstrap: [AppComponent] }) export class AppModule {}
2‐8
![Page 33: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/33.jpg)
Injektáž do komponentyexport class TaskListComponent implements OnInit {
constructor(private taskDataService: TaskDataService) { }
ngOnInit(): void { this.tasks = this.taskDataService.getTasks(); }
...}
2‐9
![Page 34: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/34.jpg)
Získání parametrů routyexport class TaskDetailComponent implements OnInit {
constructor(private route: ActivatedRoute) { }
ngOnInit(): void { let idParam = this.route.snapshot.params['id']; let id = parseInt(idParam);
... }
...}
2‐10
![Page 35: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/35.jpg)
Asynchronní datafunction onSearch(text) { let url = '/api/?q=' + text; $http .get(url) .then(function(response) { showData(response.data); }); }
onSearch('abc')
httpPromise
thenshowData(response.data)
then
Server
2‐11
![Page 36: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/36.jpg)
Asynchronní datalet search = new Subject() .map((text) => '/api/?q=' + text) .flatMap((url) => $http.get(url)) .subscribe((response) { showData(response.data); }) function onSearch(text) { return search.next(text); }
search
text -> url
url -> promise -> response
response ->
showData(response.data)
abc
onSearch('abc')
/api/?q=abc
Request
Response
onSearch('def')
def
2‐12
![Page 37: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/37.jpg)
Observable + subscribe@Component({ ...}) export class SomeComponent implements OnInit {
titleObservable: Observable<string>;
title: string;
ngOnInit() {
this.titleObservable .subscribe((title) => this.title = title); }
}
{{ title }}
2‐13
![Page 38: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/38.jpg)
Pipe@Component({ ...}) export class SomeComponent {
title: string = "Angular" }
{{ title }} -> Angular
{{ title | uppercase }} -> ANGULAR
vestavěné: date, uppercase, lowercase, currency, percent, async
2‐14
![Page 39: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/39.jpg)
Observable + async pipe@Component({ ...}) export class SomeComponent implements OnInit {
titleObservable: Observable<string>;
}
{{ titleObservable | async }}
2‐15
![Page 40: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/40.jpg)
Vyzkoušejte si to 2‐16
![Page 41: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/41.jpg)
PART 3 - BONUS 3‐0
![Page 42: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/42.jpg)
Angular 2 Formstemplate based
podobné jako v Angular 1
reac�ve
změny data jako Observable
3‐1
![Page 43: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/43.jpg)
Angular 2 Reactive Forms@Component() export class SearchComponent implements OnInit {
searchControl = new FormControl();
ngOnInit() { this.searchControl.valueChanges.subscribe(value => { // do something with value here }); } }
<input type="search" [formControl]="seachControl">
3‐2
![Page 44: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/44.jpg)
Observables - operátory 3‐3
![Page 46: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/46.jpg)
RxJS .flatMap
Podobné jako map, ale místo Observable/Promise vrací rovnou hodnoty,
nemusíte tedy zanořovat subscribe/then v map.
reac�vex.io/documenta�on/operators/flatmap.html
3‐5
![Page 49: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/49.jpg)
RxJS .distinctUntilChanged
rxmarbles.com
a mnoho dalších ‐ reac�vex.io/rxjs/manual/overview.html#categories‐of‐
operators
3‐8
![Page 50: DEVFEST 2016 - ANGULAR 2 WORKSHOP · DEVFEST 2016 - ANGULAR 2 WORKSHOP Milan Lempera Víťa Plšek Matěj Horák @milanlempera @vitaplsek @horakmat angular.cz](https://reader035.fdocumentos.com/reader035/viewer/2022062919/5ee3203cad6a402d666d3224/html5/thumbnails/50.jpg)
Vyzkoušejte si to 3‐9