Slide 1

Slide 1 text

Angular 2 The Next Framework

Slide 2

Slide 2 text

@cef62 github.com/cef62 Senior frontend engineer @ Staff member of Frontenders Verona Italian React & Angular Communities Maintainer MATTEO RONCHI

Slide 3

Slide 3 text

AngularJS history • AngularJS was originally developed in 2009 by Misko Hevery and Adam Abrons • Misko Hevery started to work for Google in 2009 • 1st release of AngularJS: 1 developer, 3 weeks, 1000 loc • AngularJS version 1.0 was released in 2012 by Google • Angular version 2 was released in September 2016 after 2 years development

Slide 4

Slide 4 text

WELCOME TO THE FUTURE

Slide 5

Slide 5 text

Angular 2 features • Optimized for both desktop and mobile • Ahead of Time (AoT) compilation • Incredible performances • Native Reactive support

Slide 6

Slide 6 text

ANGULAR 2 BASICS @INJECTABLE

Slide 7

Slide 7 text

export class MyService { getData() { return this.loadData.load(); } }

Slide 8

Slide 8 text

import { Injectable } from `angular2/core`; @Injectable() export class MyService { constructor(private loadData:LoadData) {} getData() { return this.loadData.load(); } }

Slide 9

Slide 9 text

ANGULAR 2 BASICS @COMPONENT

Slide 10

Slide 10 text

import { Component } from '@angular/core'; @Component({ selector: 'hello', template: '

Hello, {{name}}

' }) export class Hello { name: string; constructor() { this.name = 'World'; } }

Slide 11

Slide 11 text

ANGULAR 2 BASICS @DIRECTIVE

Slide 12

Slide 12 text

import { Directive, HostListener } from '@angular/core'; @Directive({ selector: `[confirm]` }) export class ConfirmDirective { @HostListener(`click`, [`$event`]) confirmFirst(event: Event) { return window.confirm( `Are you sure you want to do this?` ); } } // Usage Visit another page

Slide 13

Slide 13 text

ANGULAR 2 BASICS @PIPES

Slide 14

Slide 14 text

import { Component } from '@angular/core'; @Component({ selector: `product-price`, template: `

Price: {{ price | currency }}

` }) export class ProductPrice { price: number = 99.99; }

Slide 15

Slide 15 text

import { Pipe, PipeTransform } from '@angular/core'; const UNITS = ['B', 'KB', 'MB', 'GB']; @Pipe({ name: 'formatFileSize' }) export class FormatSize implements PipeTransform { transform( bytes: number = 0, precision: number = 2 ) : string { if (!isFinite(bytes)) return ‘?'; let unit = 0; while ( bytes >= 1024 ) { bytes /= 1024; unit ++; } return bytes.toFixed(precision) + ' ' + UNITS[unit]; } }

Slide 16

Slide 16 text

ANGULAR 2 BASICS HTTP SERVICE

Slide 17

Slide 17 text

import {Injectable} from '@angular/core'; import {Http, Response} from '@angular/http'; import {Observable} from 'rxjs'; import {Hero} from './hero'; @Injectable() export class LoadDataService { constructor(private http: Http) {} search(term: string): Observable { return this.http .get(`app/heroes/?name=${term}`) .map((r: Response) => { return r.json().data as Hero[] }); } }

Slide 18

Slide 18 text

IN THE ZONE

Slide 19

Slide 19 text

AngularJS $digest cycle • AngularJS engine is built using a dirty checking algorithm. • Application state is a single entity connected to every visual component and calculated every time a component mutates some data • It’s very easy to trigger unwanted $digest cycles impacting performances • Very difficult to debug

Slide 20

Slide 20 text

Angular 2 Change Detection engine • Based on ngZone • Recalculate the components tree state after every async interaction (events, timers, observables..) • Every component has its own Change Detector • Component’s Change Detector is generated at runtime to improve performances • Developers can control how and when components are recalculated

Slide 21

Slide 21 text

– ngBook2 “When one of the components change, no matter where in the tree it is, a change detection pass is triggered for the whole tree, from top to bottom.”

Slide 22

Slide 22 text

CD CD CD CD CD CD CD CD CHANGE DETECTION TRAVELS TOP TO BOTTOM Change Detection Flow

Slide 23

Slide 23 text

CHANGE DETECTION IS DEFINED AT COMPONENT LEVEL

Slide 24

Slide 24 text

• Every component gets a change detector responsible for checking the bindings defined in its template • ChangeDetectionStrategy • default: update the component every time data changes • onPush: update the component only when its inputs change or the component requests to be updated

Slide 25

Slide 25 text

CHANGE DETECTION (onPush) WITH IMMUTABLE DATA CD CD CD CD CD CD Change Detection Flow

Slide 26

Slide 26 text

CHANGE DETECTION (onPush) WITH OBSERVABLES CD CD CD CD Change Detection Flow

Slide 27

Slide 27 text

TYPESCRIPT: A FIRST CLASS CITIZEN

Slide 28

Slide 28 text

Why typescript • Angular2 Dependency Injection system is based on type reflection • Annotations offer a powerful and very expressive way to describe elements

Slide 29

Slide 29 text

Pros • Improve Developer Experience with better tools • Compile time error check • Type safety • Better documentation • Easy to adopt for backend developers

Slide 30

Slide 30 text

Cons • Increase project’s technical debt • Slower learning curve for traditional javascript developer • Impossible to remove without a complete rewrite

Slide 31

Slide 31 text

THINKING COMPONENTS

Slide 32

Slide 32 text

Modern web is all about components • Thinking of components instead of views improves decoupling and separation of concerns • Components are composable and highly reusable • Easier to test • UX and UI teams integrate better

Slide 33

Slide 33 text

A component is • exported as a custom HTML tag: • defined by an HTML template • enhanced using the @component decorator • controlled using its inputs and outputs • initialized by Angular Dependency Injection engine

Slide 34

Slide 34 text

SELECTOR @COMPONENT

Slide 35

Slide 35 text

import { Component } from '@angular/core'; @Component({ selector: 'hello', template: '

Hello, {{name}}

' }) export class Hello { name: string; constructor() { this.name = 'World'; } }

Slide 36

Slide 36 text

selector is the element property that we use to tell Angular to create and insert an instance of this component.

Slide 37

Slide 37 text

COMPONENT TEMPLATE @COMPONENT

Slide 38

Slide 38 text

template is an HTML string that tells Angular what needs to be to rendered in the DOM. templateUrl is a relative path to a file containing the component HTML string.

Slide 39

Slide 39 text

TEMPLATE SYNTAX • template tags {{ expression }}: Execute arbitrary expressions. Eg: {{1+1}. • property binding [key]=“value”. Used to pass data to a component. • event binding (event)=“expression”. Expression executed anytime the registered event fires. • 2-way binding Requires to import `FormsModule` to be used.

Slide 40

Slide 40 text

INPUTS @COMPONENT

Slide 41

Slide 41 text

import {Component, Input} from `@angular/ core`; @Component({ selector: `hello`, template: `

Hello, {{name}}

` }) export class Hello { @Input() name: string; }

Slide 42

Slide 42 text

import { Component } from `@angular/core`; @Component({ selector: `hello`, inputs: [`name`], template: `

Hello, {{name}}

` }) export class Hello {}

Slide 43

Slide 43 text

// To bind to a raw string // To bind to a variable in the parent scope

Slide 44

Slide 44 text

OUTPUTS @COMPONENT

Slide 45

Slide 45 text

import {Component} from `@angular/core`; @Component({ selector: `counter`, template: `

Count: {{ num }}

Increment
` }) export class Counter { num: number = 0; increment() { this.num++; } }

Slide 46

Slide 46 text

import { Component, EventEmitter, Output } from `@angular/core`; @Component({ selector: `counter`, template: `

Count: {{ count }}

Increment
` }) export class Counter { count: number = 0; @Output() result: EventEmitter = new EventEmitter(); increment() { this.result.emit(this.count); } }

Slide 47

Slide 47 text

CHILD COMPONENTS @COMPONENT

Slide 48

Slide 48 text

import {Component, ViewChild} from `@angular/ core`; import {Alert} from `./alert.component`; @Component({ selector: `app`, template: ` My alert Show Alert button>` }) export class App { @ViewChild(Alert) alert: Alert; showAlert() { this.alert.show(); } }

Slide 49

Slide 49 text

import {Component, ViewChild} from `@angular/core`; import {Alert} from `./alert.component`; @Component({ selector: `app`, template: ` My alert Show Alert` }) export class App { @ViewChild(Alert) alert: Alert; @ViewChild(`msg`) msgInput; showAlert() { const txt = this.msgInput.nativeElement.value; this.alert.show(txt); } }

Slide 50

Slide 50 text

CONTENT TRANSCLUSION @COMPONENT

Slide 51

Slide 51 text

import {Component, Input} from `@angular/core`; @Component({ selector: `hello`, template: `

Hello, {{name}}

No extra data

` }) export class Hello { @Input() name: string; } // Usage

Some other data

Some text

Slide 52

Slide 52 text

COMPONENT LIFECYCLE

Slide 53

Slide 53 text

Components & Directives shared lifecycle ngOnChanges input property value changes ngOnInit Initialization step ngDoCheck every change detection cycle ngOnDestroy before destruction

Slide 54

Slide 54 text

import { Component, OnInit } from '@angular/core'; @Component({ selector: 'hello', template: '

Hello, {{name}}

' }) export class Hello implements OnInit { name: string; constructor() { this.name = 'World'; } ngOnInit() { // do something to initialize the component } }

Slide 55

Slide 55 text

import { Directive, OnInit, OnDestroy } from '@angular/core'; @Directive({ selector: `[mySpy]` }) export class SpyDirective implements OnInit, OnDestroy { constructor(private logger: LoggerService) { } ngOnInit() { this.logIt(`onInit`); } ngOnDestroy() { this.logIt(`onDestroy`); } private logIt(msg: string) { this.logger.log(`Spy ${msg}`); } } // Usage
...

Slide 56

Slide 56 text

–Angular official docs “Angular only calls a directive/component hook method if it is defined.”

Slide 57

Slide 57 text

COMPONENT STYLE INLINE STYLES

Slide 58

Slide 58 text

import { Component } from '@angular/core'; const baseStyle = { backgroundColor: 'green', padding: '10px' }; @Component({ selector: 'hello', template: ‘

Hello!

' }) export class Hello { style: any = baseStyle; }

Slide 59

Slide 59 text

COMPONENT STYLE VIEW ENCAPSULATION

Slide 60

Slide 60 text

• Emulated (default) - styles from main HTML propagate to the component. Styles defined in this component's @Component decorator are scoped to this component only. • Native (shadow DOM)- styles from main HTML do not propagate to the component. Styles defined in this component's @Component decorator are scoped to this component only. • None - styles from the component propagate back to the main HTML and therefore are visible to all components on the page. ——— Be careful with apps that have None and Native components mixed in the application. All components with None encapsulation will have their styles duplicated in all components with Native encapsulation.

Slide 61

Slide 61 text

import { Component, ViewEncapsulation } from '@angular/core'; @Component({ selector: ‘hello', styles: [` .main { background-color: green; padding: 10px; } `], encapsulation: ViewEncapsulation.Emulated, template: `

Hello!

` }) export class Hello {}

Slide 62

Slide 62 text

// OUTPUT HTML

Hello!

// output css (inside ) .main[_ngcontent-yok-5] { background-color: green; padding: 10px; }

Slide 63

Slide 63 text

BE REACTIVE! OBSERVE ALL THE THINGS!

Slide 64

Slide 64 text

–Angular official docs “Observables open up a continuous channel of communication in which multiple values of data can be emitted over time […] Angular 2 uses observables extensively - you'll see them in the HTTP service and the event system…”

Slide 65

Slide 65 text

–A. Staltz “A stream is a sequence of ongoing events ordered in time. It can emit 3 different things: a value, an error, or a "completed" signal. Consider that the "completed" takes place, for instance, when the current window is closed.”

Slide 66

Slide 66 text

OBSERVABLES vs PROMISES

Slide 67

Slide 67 text

• Both provide us with abstractions that help us deal with the asynchronous nature of our applications. • Observables are cancellable. • Observables can be retried using one of the retry operators provided by the API, such as retry and retryWhen. • Promises require the caller to have access to the original function that returned the promise in order to have a retry capability.

Slide 68

Slide 68 text

import { Observable } from ‘rxjs/Observable'; const dataStream = new Observable((observer) => { setTimeout(() => { observer.next(42); }, 1000); setTimeout(() => { observer.next(43); }, 2000); setTimeout(() => { observer.complete(); }, 3000); }); const subscription = dataStream.subscribe( (value) => this.values.push(value), (error) => this.anyErrors = true, () => this.finished = true );

Slide 69

Slide 69 text

import { Component, OnInit, ViewChild } from `@angular/core`; import { Observable } from 'rxjs'; @Component({ selector: `app`, template: `` }) export class App implements OnInit { @ViewChild(`username`) username: any; ngOnInit(): void { Observable .fromEvent(this.username.nativeElement, 'keyup') .map((e: any) => e.target.value) .filter((text: string) => text.length > 5) .debounceTime(1000) .subscribe((text: string) => this.submit(text)); } submit(text: string): void { console.log('submitted: ', text); } }

Slide 70

Slide 70 text

Bootstrapping Angular

Slide 71

Slide 71 text

Bootstrapping is an essential process in Angular - it is where the application is loaded when Angular comes to life. Bootstrapping Angular 2 applications is certainly different from Angular 1.x, but is still a straightforward procedure.

Slide 72

Slide 72 text

// app.modules.ts import { BrowserModule } from '@angular/platform- browser'; import { NgModule } from '@angular/core'; import { HttpModule } from '@angular/http'; import { AppComponent } from './[PATH]/app.component'; import { MyComponent } from ‘./[PATH]/some.component'; import { SomeService } from “./[PATH]/some.service"; @NgModule({ declarations: [AppComponent, MyComponent], providers: [SomeService], imports: [BrowserModule, HttpModule], bootstrap: [AppComponent] }) class AppModule {}

Slide 73

Slide 73 text

// main.ts import { platformBrowserDynamic } from '@angular/ platform-browser-dynamic'; import { AppModule } from './app/'; // Bootstrap main component platformBrowserDynamic().bootstrapModule(AppModule);

Slide 74

Slide 74 text

angular-cli FAST PROJECT SETUP WORKING EXAMPLE: github.com/commit-university/exploring-angular-2

Slide 75

Slide 75 text

THANKS! @CEF62