Data Flow Patterns 
 in Angular 2 Sebastian Müller - adesso AG EnterJS - 15.06.2016
Sebastian Müller @Sebamueller
Angular 2
Components Component Tree
Component Tree Application MainNavigation UsersList UsersListEntry UsersListEntry
Die erste App import	{	Component	}	from	'@angular/core'; import	{	bootstrap	}	from	'@angular/platform-browser-dynamic'; @Component({	selector:	'my-app',	//	css	selector	template:	`	<h1>	{{title}}	</h1>	` }) export	class	AppComponent	{	title:	string	=	'my-app	works!'; } bootstrap(AppComponent);
Die erste App <html> <head> … </head> <body> <my-app>Loading...</my-app> … </body> </html>
Component Kommunikation
User App UserApp UserCard	user	=	{	username:	'admin',	email:	'admin@abc.de'	};	user
Inputs
UserApp Component UserApp UserCard import	{	Component	}	from	'@angular/core'; import	{	bootstrap	}	from	'@angular/platform-browser-dynamic'; import	{	UserCard	}	from	'./user-card.component'; @Component({	selector:	'my-app',	directives:	[UserCard],	template:	`	<user-card	[cardDetails]="user"></user>	` }) export	class	UserApp	{	user	=	{	username:	'admin',	email:	'admin@abc.de'	}; } bootstrap(UserApp);
UserCard Component UserApp UserCard import	{	Component,	Input	}	from	'@angular/core'; @Component({	selector:	'user-card',	template:	`	<div>	<h2>Username:	{{	cardDetails.username	}}</h2>	<h3>E-Mail:	{{	cardDetails.email	}}</h2>	</div>	` }) export	class	UserCard	{	@Input()	cardDetails; }
RxJS 5 Reactive Extensions
Was ist RxJS? • Library für reaktive Programmierung im 
 JavaScript Bereich • Open Source - Version 5 aktuell im Beta Status • Wird führend von Netflix entwickelt
 (Ben Lesh - @BenLesh) • Observable als wichtigster Baustein für Reaktive Programmierung
Was sind Observables?
Synchron / Pull Asynchron / Push EinValueMehrereValuesFunctions Iterators Promises Observables
„Lodash for async data“
Observable import	{	Observable	}	from	'rxjs/Observable'; var	observable	=	Observable.create(function	subscribe(observer)	{	var	i	=	0;	setInterval(()	=>	{	observer.next(i++);	},	1000); }); Lazy var	subscription	=	observable.subscribe(function	next(value)	{	console.log(value); }); 1 2 3
Observable Subscription import	{	Observable	}	from	'rxjs/Observable'; var	observable	=	Observable.create(function	subscribe(observer)	{	var	i	=	0;	var	id	=	setInterval(()	=>	{	observer.next(i++);	},	1000);	return	function	unsubscribe()	{
	console.log('unsubscribe'); clearInterval(id);	}; }); var	subscription	=	observable.subscribe(function	next(value)	{	console.log(value); }); setTimeout(()	=>	{ subscription.unsubscribe(); },	2500); 1 2 unsubscribe
subscribe() myPromise.then(function(value)	{	console.log('success',	value); },	function(err)	{	console.log('error',	err); }); myObservable.subscribe(function(value)	{	console.log('success',	value); },	function(err)	{	console.log('error',	err); }); Promise Observable
subscribe() myObservable.subscribe(function(value)	{	console.log('success',	value); },	function(err)	{	console.log('error',	err); },	function()	{	console.log('completed'); }); var	myObservable	=	Observable.create((observer)	=>	{	observer.next(1);	setTimeout(()	=>	{	observer.next(2);	observer.complete();	},	1000); }); success	1 success	2 completed
RxJS Operators
map Operator myObservable.subscribe(function(value)	{	console.log('success',	value); }); success	0 success	2 import	{	Observable	}	from	'rxjs/Observable'; import	'rxjs/add/operator/map'; var	myObservable	=	Observable.create((observer)	=>	{	var	i	=	0;	setInterval(()	=>	{	observer.next(i++);	},	1000); }).map((value)	=>	value	*	2); success	4
Weitere Operators • filter • pluck • groupBy • scan (reduce) • zip • throttle • …
Observables vs Promises Promise Observable / RxJS Liefert nur einen Wert zurück Liefert 0-n Werte Kann nicht abgebrochen werden* Kann abgebrochen werden - unsubscribe() Keine Operators Bietet Operators für Datentransformationen/ Filterung/etc. *Aktuell in Diskussion
RxJS 5 ist fest integriert
Outputs
User App UserApp UserCard	user	=	{	username:	'admin',	email:	'admin@abc.de'	};	user <user-card	[cardDetails|="user">
 </user-card>	sendEmail <user-card	[cardDetails]="user"
	(sendEmail)="showMailForm($event)">
 </user-card>
EventEmitter
UserCard Component import	{	Component,	Input,	Output,	EventEmitter	}	from	'@angular/core'; @Component({	selector:	'user-card',	template:	`	<div>	<h2>Username:	{{	cardDetails.username	}}</h2>	<h3	(click)="emailClicked()">E-Mail:	{{	cardDetails.email	}}</h2>	</div>	` }) export	class	UserCard	{	@Input()	cardDetails;	@Output()	sendEmail:	EventEmitter<string>	=	new	EventEmitter<string>();	emailClicked()	{	this.sendEmail.emit(this.cardDetails.email);	//	Observable	} }
Component Tree Application MainNavigation UsersList UsersListEntry UsersListEntry
Unidirectional Data Flow
Async Pipe
Async Pipe import	{	Component	}	from	'@angular/core'; import	{	bootstrap	}	from	'@angular/platform-browser-dynamic'; import	{	Observable	}	from	'rxjs/Observable'; @Component({	selector:	'my-app',	template:	`	<h1>	{{	counter	|	async	}}	</h1>	` }) export	class	AppComponent	{	counter:	Observable<number>	=	Observable.create((observer)	=>	{	var	i	=	0;	var	id	=	setInterval(()	=>	{	observer.next(i++);	},	1000);	return	()	=>	{	clearInterval(id);	};	}); }
Form Fields
valueChanges @Component({	selector:	'my-app',	template:	`	<form>	<input	[ngFormControl]="myInput">	</form>	{{	result	|	async	}}	` }) export	class	AppComponent	{	myInput:	Control	=	new	Control();	result:	Observable<any>;	ngOnInit()	{	this.result	=	this.myInput.valueChanges	.map((value)	=>	value	*	2);	} }
@angular/http
@angular/http • XHR Client • API basiert auf Observables • Eigenständiges Package • Mocking Features
@angular/http import	{Component}	from	'@angular/core'; import	{Http,	Response}	from	'@angular/http'; @Component({	selector:	'my-comp',	template:	`	{{	data	|	async	}}	` }) class	MyComponent	{	data:	string;	constructor(private	http:	Http)	{}	ngOnInit()	{	this.data	=	this.http.get('/my/api')	.map((r:	Response)	=>	r.json());	} }
Observables als Input
Observables als Input import	{	Component,	Input	}	from	'@angular/core'; import	{	Observable	}	from	'rxjs/Observable'; @Component({	selector:	'stock-info',	template:	`	Preis:	<b>{{	stockPrice	|	async	}}</b>	` }) export	class	StockComponent	{	@Input()	stockPrice:	Observable<number>; } <stock-info	[stockPrice]="myObservable"></stock-info>
Performance
Change Detection in Angular 2 ist sehr schnell
ChangeDetectionStrategy
Change Detection Application UserProfile Main Navigation NavEntry NavEntry	user	=	{	username:	'admin',	email:	'admin@abc.de'	}; navEntries	=	[	{name:	'a'},	{name:	'a'} ] navEntries user admin@abc.denew@abc.de	user	=	{	username:	'admin',	email:	'new@abc.de'	};
ChangeDetectionStrategy.OnPush
a === b
Change Detection Application UserProfile
 (OnPush) Main Navigation
 (OnPush) NavEntry NavEntry	user	=	{	username:	'admin',	email:	'admin@abc.de'	}; navEntries	=	[	{name:	'a'},	{name:	'a'} ] navEntries user admin@abc.de	user	=	{	username:	'admin',	email:	'new@abc.de'	}; 👎
Immutable.js + Angular 2
Immutable.js • Library für Immutable Data Structures • Open Source Projekt von Facebook • Im React Bereich weit verbreitet • TypeScript Type Definitions vorhanden • Unterstützt: • Maps • Sets • Lists (Arrays) • u.v.m.
ö var	book	=	Immutable.Map({	title:	'My	book	title' }); var	book2	=	book.set('title',	'new	title'); console.log(book	===	book2);	//	false console.log(book2.toObject());	//	{title:	'new	title’} console.log(book.toObject());	//	{title:	'My	book	title'}
DEMO
Change Detection Application UserProfile
 (OnPush) Main Navigation
 (OnPush) NavEntry NavEntry	user	=	{	username:	'admin',	email:	'admin@abc.de'	}; navEntries	=	[	{name:	'a'},	{name:	'a'} ] navEntries user admin@abc.denew@abc.de user	=	user.set(
	'email',
	'new@abc.de'
 ) "
Talk:
 Angular 2 Change Detection erklärt
 Pascal Precht
Fazit
Fazit • Angular 2 bietet viele nützliche Wege zur Kommunikation • Einarbeitung in RxJS kostet viel Zeit • Aber es lohnt sich! • Angular 2 Change Detection ist sehr schnell • ChangeDetectionStrategy.OnPush wenn möglich einsetzen
Danke! EnterJS - 15.06.2016 @Sebamueller

Data Flow Patterns in Angular 2 - Sebastian Müller