http://ramonmr.com/wp-content/uploads/2015/05/Google-Material-Design-Wallpaper.jpg
“
“
“
Wassim Chegham @manekinekko
Developer Advocate at SFEIR
Google Developer Expert (GDE) in Angular
global network of experienced product strategists, designers, developers and marketing professionals that actively support developers and startups.
TIME
TO LEARN ANGULAR 2
Angular 2
is built using
TypeScript
ES5
ES2015
ES2016
TS
ES+
you can use TypeScript
ES6/7 or ES5
you must
learn ES2015+
bit.ly/learn-es2015 - Learn ES6 (french only)
you should learn TypeScript
https://plus.google.com/photos/+AlejandroDeLaRosa05/albums/6110903958455761281/6110904013763089538?sqi=109024875292709480869&sqsi=c3d26bbe-f1d7-4759-92bf-1df7959cd77c&pid=6110904013763089538&oid=114772705002835242470
https://github.com/manekinekko/angular2-codelab
https://github.com/manekinekko/angular2-codelab/STEPS.md
BREAK TIME
YOUR APP
IS A TREE OF
SELF-DESCRIBING
COMPONENTS
import {Component} from '@angular/core';
@Component({
/* configuration */
})
class Application {
/* ... */
}
import {Component} from '@angular/core';
import { bootstrap } from '@angular/platform-browser-dynamic';
@Component({
/* configuration */
})
class Application {
/* ... */
}
bootstrap(Application, [ /* deps */ ])
BREAK TIME
COMPONENTS HAVE
TEMPLATES
<!-- 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
HAVE
LIFECYCLES
class Application {
ngOnInit() {}
ngOnDestroy() {}
ngDoCheck() {}
ngOnChanges(records) {}
ngAfterContentInit() {}
ngAfterContentChecked() {}
ngAfterViewInit() {}
ngAfterViewChecked() {}
}
import {Component} from '@angular/core';
@Component({
/* configuration */
})
class Application {
/* ... */
ngOnInit() {
// Properties are resolved and things like
// this.mapWindow and this.mapControls
// had a chance to resolve from the
// two child components <map-window> and <map-controls>
}
}
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');
}
}
BREAK TIME
COMPONENTS ARE
ROUTABLE
import { ROUTER_DIRECTIVES, RouteConfig } from '@angular/router-deprecated';
@Component({
selector: 'app',
template: `
<h1>Component Router</h1>
<nav>
<a [routerLink]="['Customers']">Customers</a>
<a [routerLink]="['Orders', {id: order.id}]">Orders</a>
</nav>
<router-outlet></router-outlet>
`,
directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
{ path: '/', name: 'Customers', component: CustomersComponent, useAsDefault: true },
{ path: '/orders/:id', name: 'Orders', component: OrdersComponent },
{ path: '/details/...', name: 'OrderDetails', component: DetailsComponent }
])
export class AppComponent {
constructor(private params: RouteParams) {
let id = this.params.get('id');
}
}
import {provide} from '@angular/core';
import { bootstrap } from '@angular/platform-browser-dynamic';
import {AppComponent} from './app.component';
import {
ROUTER_PROVIDERS,
PathLocationStrategy,
LocationStrategy // or HashLocationStrategy
} from '@angular/router-deprecated';
bootstrap(AppComponent, [
ROUTER_PROVIDERS,
provide(LocationStrategy, {
useClass: PathLocationStrategy // or HashLocationStrategy
})
]);
BREAK TIME
COMPONENTS CAN CONTAIN
PROVIDERS
import { Component } from '@angular/core';
import { DataStore } from './my-store';
@Component({
selector: 'home',
providers: [ DataStore ],
//...
})
export class Home {
private data: any[];
constructor(data: DataStore){
this.data = data.someAPI();
}
}
import { bootstrap } from '@angular/platform-browser-dynamic';
import {ROUTER_PROVIDERS} from '@angular/router';
import {MyApp} from './app/ng2-codelab';
bootstrap(MyApp,[
ROUTER_PROVIDERS,
//...
]);
import { Component, provide } from '@angular/core';
import { DataStore } from './my-store';
@Component({
providers: [ DataStore ]
})
export class Home { /* */ }
[ provide(DataStore, {useClass: DataStore}) ]
// values
provide(String, {useValue: 'Hello World'})
// aliases
provide(DataStore, {useClass: DataStore})
provide(MockedDataStore, {useExisting: DataStore})
// factories
provide(DataStore, {
useFactory: (dep1, dep2) => {
return new DataStore(dep1, dep2);
},
deps: [Dep1, Dep2]
})
BREAK TIME
COMPONENTS CAN USE
PIPES
PIPES
ARE LIKE NG1 FILTERS
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'trim'
})
export class TrimPipe implements PipeTransform {
transform(value: any) {
if (!value) {
return '';
}
return value.trim();
}
}
DatePipe,
UpperCasePipe,
LowerCasePipe,
CurrencyPipe,
PercentPipe
...
BREAK TIME
COMPONENTS CAN USE
DIRECTIVES
THEY ARE CALLED ATTRIBUTES
DIRECTIVES
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>
(click on the envelop)
manekinekko