Wassim Chegham PRO
Senior Developer Advocate @Microsoft ★ Angular contributor ★ Bazel contributor ★ GDE @Google ★ creator of @itsjustangular / hueaction.dev / ngx.tools / xlayers.dev / angular.run / thundr.dev
Wassim Chegham
Dev Advocate
@manekinekko
Global network of experienced, designers and developers that actively support developers and startups.
TIME
TO LEARN ANGULAR 2
Angular 2
is built using
TypeScript
ES5
ES2015
ES2016
TS
ES+
you should learn TypeScript
you must
learn ES6+
bit.ly/learn-es2015 - Discover ES6 (french only)
YOUR APP
IS A TREE OF
SELF-DESCRIBING
MODULES & COMPONENTS
AppModule
CoreModule
FeaturesModule
SharedModule
AppModule
CoreModule
import { NgModule } from '@angular/core';
@NgModule({
imports: [],
declarations: [],
providers: [],
exports: [],
bootstrap: []
})
class AppModule { }
import {Component} from '@angular/core';
@Component({
/* configuration */
})
class Application {
/* ... */
}
<!-- index.html -->
<my-root>
Your application is loading...
</my-root>
// app.component.ts
import { Component } from '@angular/core';
import { Toolbar } from './app-shell/toolbar/toolbar';
@Component({
selector: 'my-root'
template: `<my-toolbar></my-toolbar>`
})
export class ApplicationHome { /* ... */ }
COMPONENTS
HAVE
LIFECYCLES
import { platformBrowserDynamic }
from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
import {Component} from '@angular/core';
@Component({
/* configuration */
})
class Application {
/* ... */
ngOnInit() { /* ... */ }
}
class Application {
ngOnInit()
ngOnDestroy()
ngDoCheck()
ngOnChanges(changes)
ngAfterContentInit()
ngAfterContentChecked()
ngAfterViewInit()
ngAfterViewChecked()
}
COMPONENTS HAVE
TEMPLATES
<div>
Hello {{ you }}.
</div>
<my-menu [items]="mainMenu"></my-menu>
<img [src]="imageUrl" />
<my-menu-item
(click)="clicked($event)" (yolo)="callFunc($event)"
></my-menu-item>
// application.ts
@Component({...})
class Application {
clicked(event) {}
callFunc(param) {}
}
<input name="you" [(ngModel)]="you">
<!-- is equivalent to this -->
<input name="you" [ngModel]="you"
(ngModelChange)="you = $event" >
<!-- properties binding -->
<input [value]="firstName">
<div [style.width.px]="mySize">
<label [attr.for]="someName"></label>
<!-- event binding -->
<button (click)="readRainbow($event)">
<!-- two way binding -->
<my-cmp [(title)]="name">
<!-- builtin directives -->
<section *ngIf="showSection">
<li *ngFor="let item of list">
<!-- ...etc -->
COMPONENTS
ARE
DIRECTIVES
THREE
TYPES OF DIRECTIVES
STRUCTURAL
CHANGES THE DOM LAYOUT
<li
*ngIf="isFooBar"
*ngFor="let card of dataStore.items;
trackBy:customTrackBy">
</li>
STRUCTURAL
<my-items-card *ngFor="let card of dataStore.items;
trackBy:customTrackBy">
{{ card }}
</my-items-card>
<!-- is equivalent to this -->
<template ngFor let-card [ngForOf]="dataStore.items"
[ngForTrackBy]="customTrackBy">
<my-items-card>{{ card }}</my-items-card>
</template>
ATTRIBUTES
CHANGES THE BEHAVIOR OF THE ELEMENT
<div
[style.width.px]="mySize">
</div>
ATTRIBUTES
import {
Directive,
ElementRef,
Renderer,
} from '@angular/core';
@Directive({
selector: '[myHighlight]'
})
export class MyHighlightDirective {
constructor(el: ElementRef, renderer: Renderer) {
renderer
.setElementStyle(
el.nativeElement,
'backgroundColor',
'yellow'
);
}
}
<span myHighlight >Highlight me!</span>
import {Directive, ElementRef, Renderer} from '@angular/core';
@Directive({
selector: '[x-large]'
})
export class XLarge {
constructor(element: ElementRef, renderer: Renderer) {
renderer.setElementStyle(
element.nativeElement, 'fontSize', 'x-large'
);
}
}
DO NOT EVER NEVER TOUCH THE DOM!
renderer.setElementStyle(
el.nativeElement,
'backgroundColor',
'yellow'
);
COMPONENT
JUST A DIRECTIVE WITH A TEMPLATE
<my-component>
Loading...
</my-component>
COMPONENT
COMPONENTS CAN DISPLAY FORMATTED DATA
THANKS TO
PIPES
JUST LIKE
ANGULAR 1
FILTERS
BUILT-INS PIPES
DatePipe,
UpperCasePipe,
LowerCasePipe,
CurrencyPipe,
PercentPipe...etc
CUSTOM PIPE
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'trim'
})
export class TrimPipe implements PipeTransform {
transform(value: any) {
if (!value) {
return '';
}
return value.trim();
}
}
PIPES CAN BE STATEFUL
ASYNC PIPE
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'fetch',
pure: false
})
export class FetchJsonPipe {
private fetchedValue:any;
private fetchPromise:Promise<any>;
transform(value:string, args:string[]):any {
this.fetchPromise = window.fetch(value)
.then((result:any) => result.json())
.then((json:any) => this.fetchedValue = json);
return this.fetchedValue;
}
}
ASYNC PIPE
<div>
{{'heroes.json' | fetch | json}}
</div>
COMPONENTS
CAN HAVE
STATE
[ property binding ]
( event binding )
import {Component, Input, AfterViewInit, EventEmitter} from '@angular/core';
@Component({
/* configuration */
})
export class ThemeCard implements AfterViewInit {
@Input() inputProperty: string;
@Output() outputEvent: EventEmitter<string>;
constructor() {
this.outputEvent = new EventEmitter<string>();
}
ngAfterViewInit() {
console.log(this.inputProperty);
}
onClick() {
this.outputEvent.emit('foo');
}
}
COMPONENTS ARE
ROUTABLE
// app.routes.ts
import { RouterModule } from '@angular/router';
import { CatComponent } from './cats/';
const routes = [
{path: '', redirectTo: 'cat'},
{path: 'cat', component: CatComponent}
];
export const Routes = RouterModule.forRoot(routes);
// app.routes.ts
import { RouterModule } from '@angular/router';
import { CatComponent } from './cats/';
const routes = [
{path: '', redirectTo: 'cat'},
{path: 'cat', loadChildren: 'app/cat/cat.module#CatModule'}
];
export const Routes = RouterModule.forRoot(routes);
// app.routes.ts
import { RouterModule } from '@angular/router';
import { CatComponent, AuthGuard, CatResolver } from './cats/';
const routes = [
{path: '', redirectTo: 'cat'},
{
path: 'cat',
canActivate: [ AuthGuard ],
resolve: { cats: CatResolver },
loadChildren: 'app/cat/cat.module#CatModule'
}
];
export const Routes = RouterModule.forRoot(routes);
import { NgModule } from '@angular/core';
import { Routes } from './app/app.routes';
@NgModule({
imports: [ ..., Routes ],
...
})
// app.component.ts
@Component({
selector: 'my-app',
template: `
<h1>Component Router</h1>
<nav>
<a [routerLink]="['cat']">Cat</a>
</nav>
<router-outlet></router-outlet>
`
})
export class AppComponent {
constructor() {}
}
COMPONENTS CAN USE
SERVICES
import { Component } from '@angular/core';
import { DataStore } from './my-store.service';
@Component({
selector: 'home',
providers: [ DataStore ],
//...
})
export class Home {
private data: any[];
constructor(data: DataStore){
this.data = data.someAPI();
}
}
import { NgModule } from '@angular/core';
import { DataStore } from './my-store.service';
@NgModule({
providers: [ ..., DataStore ],
...
})
import { Component, provide } from '@angular/core';
import { DataStore } from './my-store.service';
@Component({
providers: [ DataStore ]
})
export class Home { /* */ }
{ provide: DataStore, useClass: DataStore }
// values
{provide: Token, useValue: 'Hello World' }
// aliases
{provide: DataStore, useClass: DataStore }
{provide: MockedDataStore, useExisting: DataStore }
// factories or configurable instances
{provide: DataStore, useFactory: (dep1, dep2) => {
return new DataStore(dep1, dep2);
},
deps: [Dep1, Dep2]
}
SUPPORTED LANGUAGES
EDITORS SUPPORT
Angular2 and TypeScript support
BUILD SYSTEMS
CHECK OUT THE NEW ANGULAR CLI
UPGRADING TO ANGULAR 2+ OFFICIAL DOCUMENTATION
(click on icon to open link)
THANKS TO FELLOW GDEs
Faster development and errors prevention, thanks to Classes, TypeScript and Decorators...
Set up the build system can be hard...
We have a CLI...
Faster change detection (up to 10x times faster) and faster overall performance (up to 2.5x times or more)...
People don't seem to like the template syntax...
Com'on, this is just syntax.
Future proof with support for web, mobile, server-side rendering and native...
Lack of convention?
The Style guides are here!
Great browser support. Internet Explorer 9 and plus...
Some developers are turned off by Dependency Injection...
sorry for you guys!
No long tied to the browser. Angular 2+ can run anywhere (server, mobile, web worker, etc.)...
SOME THOUGHTS...
A2 has all the concepts of A1 but is better in every way...
Your skills from A1 have already prepared you for A2...
Ng2 is built upon Web Standards, if you know the Web then you know ng2...
Ng2 is not just a framework, it is a modular platform.
manekinekko
By Wassim Chegham
This is an overview od the new concepts of Angular2.
Senior Developer Advocate @Microsoft ★ Angular contributor ★ Bazel contributor ★ GDE @Google ★ creator of @itsjustangular / hueaction.dev / ngx.tools / xlayers.dev / angular.run / thundr.dev