Mikael Couzic
<div>
Name: <input ng-model="name">
<h1>Hello {{name}} !</h1>
</div>
@Component({
selector: 'my-app',
template: `
<div>
Name: <input [(ngModel)]="name">
<h1>Hello {{name}} !</h1>
</div>
`,
})
export class App {
}
@Component({
selector: 'my-app',
template: `
<div>
Name: <input (keyup)="onNameKeyUp($event)">
<h1>Hello {{name}} !</h1>
</div>
`,
})
export class App {
name: string
onNameKeyUp(event: KeyboardEvent) {
this.name = event.target.value
}
}
@Component({
selector: 'my-app',
template: `
<div>
Name: <input #name (keyup)=0>
<h1>Hello {{name.value}} !</h1>
</div>
`,
})
export class App {
}
@Component({
selector: 'my-app',
template: `
<div>
Name: <input [formControl]="name">
<h1>Hello {{name.value}} !</h1>
</div>
`,
})
export class App {
name = new FormControl()
}
ES5
ESNext
TypeScript
Compatible avec JavaScript
Types statiques
Détection d'erreurs dès la compilation
Auto-complétion, refactorings...
Flexibilité du typage structurel
Accessible aux développeurs Java et C#
Variables et constantes :
let n: number = 1
const s: string = 'Hello'
Paramètres de fonctions :
function f(i: number) { ... }
Retour de fonction :
function f(): number {
return 42
}
Le compilateur TypeScript induit les types des variables et retours de fonctions non annotés
let n = 1 // let n: number = 1
let s = "Hello World" // let s: string = "Hello World"
n = s; // COMPILATION ERROR
s = n; // COMPILATION ERROR
function f() { // function f(): string {
return "hello"
}
L'équivalent TypeScript du type dynamique
const n: number = 1
const s: string = 's'
function print(a: any) {
console.log(a)
}
print(n)
print(s)
const n = 1
const s = 's'
function printUnion(u: number | string) {
console.log(u)
}
printUnion(n)
printUnion(s)
printUnion(false) // COMPILATION ERROR
const n = 1
const s = 's'
type Printable = number | string
function printAlias(p: Printable) {
console.log(p)
}
printAlias(n)
printAlias(s)
interface Person {
name: string
age: number
}
interface Client extends Person {
id: number
address: {
street: string
city: string
}
}
interface Person {
name: string
age: number
}
function sayHello(person: Person): string {
return 'Hello, ' + person.name
}
const bob: Person = {
name: 'Bob',
age: 7
}
sayHello(bob)
sayHello({
name: 'John',
age: 42
})
type Drink = 'juice' | 'beer' | 'wine'
function serve(drink: Drink) {}
serve('juice')
const alcoolVolumeByDrink: Record<Drink, number> = {
juice: 0,
beer: 4.5,
wine: 12
}
const wineAlcoolVolume = alcoolVolumeByDrink.wine
@Component
@View
@Directive
@Animation
@Inject
@InjectLazy
@Optional
@Host
@Parent
@Pipe
@Property
@NgModule
@RouteConfig
@HostBinding
@HostEvent
@Injectable
@ViewChild
@ViewChildren
@Input
@Output
@Attribute
@CanActivate
import {Component} from '@angular/core';
@Component({
selector: 'greeter',
template: `<h1>Hello !</h1>`
})
class GreeterComponent {}
<greeter></greeter>
import {Component} from '@angular/core';
@Component({
selector: 'greeter',
styles: [`
.message {
color: red;
}
`],
template: `<h1 class="message">Hello !</h1>`
})
class GreeterComponent {}
<greeter></greeter>
import {Component, Input} from '@angular/core';
@Component({
selector: 'tab',
template: `<section class="tab">
<h1>This is a Tab</h1>
<!-- Le contenu de la balise <tab> sera inséré ici -->
<ng-content></ng-content>
</section>`
})
export class TabComponent {}
<tab>
<h2>Tab Content</h2>
</tab>
@Component(...)
export class MyComponent {
constructor() { }
ngOnInit() {}
ngOnDestroy() {}
ngDoCheck() {}
ngOnChanges(records) {}
ngAfterContentInit() {}
ngAfterContentChecked() {}
ngAfterViewInit() {}
ngAfterViewChecked() {}
}
Callback appelés à différents moments de la vie du component.
import {Component, OnInit} from '@angular/core'
@Component()
export class myComponent implements OnInit{
constructor() { /* Injection de dépendance */ }
ngOnInit() { /* code à executer à l'initialisation */ }
}
Utiliser les interfaces !!!
Au lieu de charger le constructeur pour rien, privilégier l'utilisation de ngOnInit()
Manipule le DOM pour ajouter ou supprimer des éléments (NgIf, NgFor...)
On utilise le préfixe "*" (astérisque)
<p *ngIf="condition">
condition is true and ngIf is true.
</p>
<div *ngIf="false"></div>
<div *ngIf="a > b"></div>
<div *ngIf="str == 'yes'"></div>
<div *ngIf="myFunc()"></div>
Permet d'afficher un élément selon la valeur d'une expression booléenne.
Une alternative consiste à utiliser :
<div [hidden]="someProp">I am hidden</div>
<div *ngIf="myVar == 'A'">Var is A</div>
<div *ngIf="myVar == 'B'">Var is B</div>
<div *ngIF="myVar == 'C'">Var is C</div>
<div *ngIf="myVar != 'A' && myVar != 'B' && myVar != 'C'"></div>
<div [ngSwitch]="myVar">
<div *ngSwitchCase="A">Var is A</div>
<div *ngSwitchCase="B">Var is B</div>
<div *ngSwitchCase="C">Var is C</div>
<div *ngSwitchDefault>Var is something else</div>
</div>
import {Component} from '@angular/core'
@Component({
selector: 'todo-list',
template: `
<h2>Todos</h2>
<ul>
<li *ngFor="let todo of todos">{{todo}}</li>
</ul>
`
})
export class TodoList {
todos = ['Walk the dog', 'Stay in bed', 'Code more']
}
import {Component} from '@angular/core'
@Component({
selector: 'todo-list',
template: `
<h2>Todos</h2>
<ul>
<li *ngFor="let todo of todos; let i = index">
{{i}} : {{todo}}
</li>
</ul>
`
})
export class TodoList {
todos = ['Walk the dog', 'Stay in bed', 'Code more']
}
RootComp
ChildComp1
ChildComp1
[property]="expression"
(event)="update()"
@Input()
@Output()
<div [style.color]="'red'">I'm red !</div>
Accès à toutes les propriétés des éléments du DOM :
@Input()
Même syntaxe pour les composants custom :
<greeter [name]="'John'"></greeter>
import {Component, Input} from '@angular/core'
@Component({
selector: 'greeter',
template: `<h1>Hello, {{ name }} !</h1>`
})
export class GreeterComponent {
@Input() name: string;
}
<greeter [name]="'John'"></greeter>
<button (click)="doSomething()">Click Me</button>
Accès à tous les évènements natifs du DOM :
@Output()
Même syntaxe pour les composants Angular :
<greeter (greet)="doSomething()"></greeter>
import {Component, Output, EventEmitter} from '@angular/core'
@Component({
selector: 'greeter',
template: `<div (click)="onClick()">
{{message}}
</div>`
})
export class GreeterComponent {
message = 'Hello !'
@Output() greet = new EventEmitter<string>();
onClick() {
this.greet.emit(this.message);
}
}
<greeter (greet)="doSomething($event)"></greeter>
import {NgModule} from '@angular/core'
import {CommonModule} from '@angular/common'
import {GreeterComponent} from './greeter.component'
@NgModule({
imports: [CommonModule],
declarations: [GreeterComponent],
exports: [GreeterComponent]
})
export class GreeterModule {
}
{{ collectionOfUsers | orderBy:'firstName' | limitTo:5 }}
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'uppercase'
})
export class UpperCasePipe implements PipeTransform {
transform(value: String, args: any[]) {
return value.toUpperCase();
}
}
import {Component, View} from '@angular/core';
import {UpperCasePipe} from './UpperCasePipe'
@Component({
selector: 'widget1',
template: `<div>{{'Va passer dans le pipe' | uppercase}}</div>`
})
export class Widget1{}
@NgModule({
declarations: [Widget1, UpperCasePipe],
exports: [Widget1]
})
import {Injectable} from '@angular/core'
@Injectable()
export class GreeterService {
greet(name: string): string {
return `Hello, ${name} !`
}
}
import {NgModule} from '@angular/core'
import {GreeterService} from './greeter.service'
@NgModule({
providers: [GreeterService]
})
export class GreeterModule {
}