+ All Categories
Home > Software > Commit University - Exploring Angular 2

Commit University - Exploring Angular 2

Date post: 16-Apr-2017
Category:
Upload: commit-university
View: 269 times
Download: 3 times
Share this document with a friend
76
Exploring Angular 2
Transcript
Page 1: Commit University - Exploring Angular 2

Exploring Angular 2

Page 2: Commit University - Exploring Angular 2

Angular 2

The Next Framework

Page 3: Commit University - Exploring Angular 2

@cef62

github.com/cef62

Senior frontend engineer @

Staff member of Frontenders Verona

Italian React & Angular Communities Maintainer

MATTEO RONCHI

Page 4: Commit University - Exploring Angular 2

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

Page 5: Commit University - Exploring Angular 2

WELCOME TO THE FUTURE

Page 6: Commit University - Exploring Angular 2

Angular 2 features

• Optimized for both desktop and mobile

• Ahead of Time (AoT) compilation

• Incredible performances

• Native Reactive support

Page 7: Commit University - Exploring Angular 2

ANGULAR 2 BASICS

@INJECTABLE

Page 8: Commit University - Exploring Angular 2

export class MyService {

getData() { return this.loadData.load(); } }

Page 9: Commit University - Exploring Angular 2

import { Injectable } from `angular2/core`;

@Injectable() export class MyService { constructor(private loadData:LoadData) {}

getData() { return this.loadData.load(); } }

Page 10: Commit University - Exploring Angular 2

ANGULAR 2 BASICS

@COMPONENT

Page 11: Commit University - Exploring Angular 2

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

@Component({ selector: 'hello', template: '<p>Hello, {{name}}</p>' }) export class Hello { name: string;

constructor() { this.name = 'World'; } }

Page 12: Commit University - Exploring Angular 2

ANGULAR 2 BASICS

@DIRECTIVE

Page 13: Commit University - Exploring Angular 2

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 <button type="button" (click)="visitOtherPage()" confirm>Visit another page</button>

Page 14: Commit University - Exploring Angular 2

ANGULAR 2 BASICS

@PIPES

Page 15: Commit University - Exploring Angular 2

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

@Component({ selector: `product-price`, template: `<p>Price: {{ price | currency }}</p>` }) export class ProductPrice { price: number = 99.99; }

Page 16: Commit University - Exploring Angular 2

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]; } }

Page 17: Commit University - Exploring Angular 2

ANGULAR 2 BASICS

HTTP SERVICE

Page 18: Commit University - Exploring Angular 2

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<Hero[]> { return this.http .get(`app/heroes/?name=${term}`) .map((r: Response) => { return r.json().data as Hero[] }); } }

Page 19: Commit University - Exploring Angular 2

IN THE ZONE

Page 20: Commit University - Exploring Angular 2

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

Page 21: Commit University - Exploring Angular 2

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

Page 22: Commit University - Exploring Angular 2

– 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.”

Page 23: Commit University - Exploring Angular 2

CD

CD CD

CD CD CD

CD CD

CHANGE DETECTION TRAVELS TOP TO BOTTOM

Chan

ge D

etec

tion

Flow

Page 24: Commit University - Exploring Angular 2

CHANGE DETECTION IS DEFINED AT COMPONENT LEVEL

Page 25: Commit University - Exploring Angular 2

• 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

Page 26: Commit University - Exploring Angular 2

CHANGE DETECTION (onPush) WITH IMMUTABLE DATA

CD

CD

CD CD

CD CD Chan

ge D

etec

tion

Flow

Page 27: Commit University - Exploring Angular 2

CHANGE DETECTION (onPush) WITH OBSERVABLES

CD

CD

CD

CDChan

ge D

etec

tion

Flow

Page 28: Commit University - Exploring Angular 2

TYPESCRIPT: A FIRST CLASS CITIZEN

Page 29: Commit University - Exploring Angular 2

Why typescript

• Angular2 Dependency Injection system is based on type reflection

• Annotations offer a powerful and very expressive way to describe elements

Page 30: Commit University - Exploring Angular 2

Pros

• Improve Developer Experience with better tools

• Compile time error check

• Type safety

• Better documentation

• Easy to adopt for backend developers

Page 31: Commit University - Exploring Angular 2

Cons

• Increase project’s technical debt

• Slower learning curve for traditional javascript developer

• Impossible to remove without a complete rewrite

Page 32: Commit University - Exploring Angular 2

THINKING COMPONENTS

Page 33: Commit University - Exploring Angular 2

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

Page 34: Commit University - Exploring Angular 2

A component is

• exported as a custom HTML tag: <tab-bar />

• defined by an HTML template

• enhanced using the @component decorator

• controlled using its inputs and outputs

• initialized by Angular Dependency Injection engine

Page 35: Commit University - Exploring Angular 2

SELECTOR

@COMPONENT

Page 36: Commit University - Exploring Angular 2

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

@Component({ selector: 'hello', template: '<p>Hello, {{name}}</p>' }) export class Hello { name: string;

constructor() { this.name = 'World'; } }

Page 37: Commit University - Exploring Angular 2

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

Page 38: Commit University - Exploring Angular 2

COMPONENT TEMPLATE

@COMPONENT

Page 39: Commit University - Exploring Angular 2

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.

Page 40: Commit University - Exploring Angular 2

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 <input [(ngModel)]=“u.name"> Requires to import `FormsModule` to be used.

Page 41: Commit University - Exploring Angular 2

INPUTS

@COMPONENT

Page 42: Commit University - Exploring Angular 2

import {Component, Input} from `@angular/core`;

@Component({ selector: `hello`, template: `<p>Hello, {{name}}</p>` }) export class Hello { @Input() name: string; }

Page 43: Commit University - Exploring Angular 2

import { Component } from `@angular/core`;

@Component({ selector: `hello`, inputs: [`name`], template: `<p>Hello, {{name}}</p>` }) export class Hello {}

Page 44: Commit University - Exploring Angular 2

// To bind to a raw string <hello name="World"></hello>

// To bind to a variable in the parent scope <hello [name]="userName"></hello>

Page 45: Commit University - Exploring Angular 2

OUTPUTS

@COMPONENT

Page 46: Commit University - Exploring Angular 2

import {Component} from `@angular/core`;

@Component({ selector: `counter`, template: ` <div> <p>Count: {{ num }}</p> <button (click)="increment()">Increment</button> </div> ` }) export class Counter { num: number = 0;

increment() { this.num++; } }

Page 47: Commit University - Exploring Angular 2

import { Component, EventEmitter, Output } from `@angular/core`;

@Component({ selector: `counter`, template: ` <div> <p>Count: {{ count }}</p> <button (click)="increment()">Increment</button> </div> ` }) export class Counter { count: number = 0; @Output() result: EventEmitter = new EventEmitter();

increment() { this.result.emit(this.count); } }

Page 48: Commit University - Exploring Angular 2

CHILD COMPONENTS

@COMPONENT

Page 49: Commit University - Exploring Angular 2

import {Component, ViewChild} from `@angular/core`; import {Alert} from `./alert.component`;

@Component({ selector: `app`, template: ` <my-alert>My alert</my-alert> <button (click)="showAlert()">Show Alert</button>` }) export class App { @ViewChild(Alert) alert: Alert;

showAlert() { this.alert.show(); } }

Page 50: Commit University - Exploring Angular 2

import {Component, ViewChild} from `@angular/core`; import {Alert} from `./alert.component`;

@Component({ selector: `app`, template: ` <my-alert>My alert</my-alert> <input #msg type=“text” /> <button (click)="showAlert()">Show Alert</button>` }) export class App { @ViewChild(Alert) alert: Alert; @ViewChild(`msg`) msgInput;

showAlert() { const txt = this.msgInput.nativeElement.value; this.alert.show(txt); } }

Page 51: Commit University - Exploring Angular 2

CONTENT TRANSCLUSION

@COMPONENT

Page 52: Commit University - Exploring Angular 2

import {Component, Input} from `@angular/core`;

@Component({ selector: `hello`, template: `<div> <p>Hello, {{name}}</p> <ng-content><p>No extra data</p></ng-content> </div>` }) export class Hello { @Input() name: string; }

// Usage

<hello name=“Matteo”> <div> <h1>Some other data</h1> <p>Some text</p> </div> </hello>

Page 53: Commit University - Exploring Angular 2

COMPONENT LIFECYCLE

Page 54: Commit University - Exploring Angular 2

Components & Directives shared lifecycle

ngOnChanges input property value changes

ngOnInit Initialization step

ngDoCheck every change detection cycle

ngOnDestroy before destruction

Page 55: Commit University - Exploring Angular 2

import { Component, OnInit } from '@angular/core';

@Component({ selector: 'hello', template: '<p>Hello, {{name}}</p>' }) export class Hello implements OnInit { name: string;

constructor() { this.name = 'World'; }

ngOnInit() { // do something to initialize the component } }

Page 56: Commit University - Exploring Angular 2

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 <div mySpy>...</div>

Page 57: Commit University - Exploring Angular 2

–Angular official docs

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

Page 58: Commit University - Exploring Angular 2

COMPONENT STYLE

INLINE STYLES

Page 59: Commit University - Exploring Angular 2

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

const baseStyle = { backgroundColor: 'green', padding: '10px' }; @Component({ selector: 'hello', template: ‘<p [ngStyle]="style">Hello!</p>' }) export class Hello { style: any = baseStyle; }

Page 60: Commit University - Exploring Angular 2

COMPONENT STYLE

VIEW ENCAPSULATION

Page 61: Commit University - Exploring Angular 2

• 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.

Page 62: Commit University - Exploring Angular 2

import { Component, ViewEncapsulation } from '@angular/core';

@Component({ selector: ‘hello', styles: [` .main { background-color: green; padding: 10px; } `], encapsulation: ViewEncapsulation.Emulated, template: `<p class="main">Hello!</p>` }) export class Hello {}

Page 63: Commit University - Exploring Angular 2

// OUTPUT HTML <p class="main" _ngcontent-yok-5="" >Hello!</p>

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

Page 64: Commit University - Exploring Angular 2

BE REACTIVE!

OBSERVE ALL THE THINGS!

Page 65: Commit University - Exploring Angular 2

–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…”

Page 66: Commit University - Exploring Angular 2

–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.”

Page 67: Commit University - Exploring Angular 2

OBSERVABLES vs PROMISES

Page 68: Commit University - Exploring Angular 2

• 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.

Page 69: Commit University - Exploring Angular 2

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 );

Page 70: Commit University - Exploring Angular 2

import { Component, OnInit, ViewChild } from `@angular/core`; import { Observable } from 'rxjs';

@Component({ selector: `app`, template: `<input type="text" #username />` }) 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); } }

Page 71: Commit University - Exploring Angular 2

Bootstrapping Angular

Page 72: Commit University - Exploring Angular 2

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.

Page 73: Commit University - Exploring Angular 2

// 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 {}

Page 74: Commit University - Exploring Angular 2

// main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/';

// Bootstrap main component platformBrowserDynamic().bootstrapModule(AppModule);

Page 75: Commit University - Exploring Angular 2

angular-cli

FAST PROJECT SETUP

WORKING EXAMPLE: github.com/commit-university/exploring-angular-2

Page 76: Commit University - Exploring Angular 2

THANKS!

@CEF62


Recommended