Enhance Web Development
Angular 2
Presentation
- Qui suis-je ?
- Agenda
- Quelques règles !
- Les outils nécessaires
Qui suis-je ?
- Développeur Enthousiaste !
- CTO & Co-founder @ EliumTV (6 mois)
- Directeur Frontend @ Teads (4 ans)
- Webdev depuis 1998
@blongearet
firehist
Benjamin Longearet
Agenda
Jour 1
Matinée
- Accueil & Agenda
- Pourquoi Angular 2 ?
- Le panorama
- Environnement de développement
- Les composants fondamentaux
Jour 1
Après-midi
- Les tests
- Les templates
- Les composants / directives
- Les pipes
- Les services
- Communication avec le serveur
Jour 2
Matinée
- Le routeur
- Les formulaires
- Les tests avancées
Jour 2
Après-midi
- La programmation Réactive
- L'immutabilité
- Les Observables et RxJS
- Les Stores / States
Semaine 1
Jour 5
- Le routeur
- Comprendre une architecture orientée composant
Semaine 2
Jour 1
- Bien utiliser son navigateur
- Versionner son code source
Semaine 2
Jour 2
- Les directives
- Les pipes
Semaine 2
Jour 3
- Communication avec un serveur
- Firebase : Kezako !
Semaine 2
Jour 4
- Panorama de la programmation Reactive
- Les Observables et RxJS
- Les opérations immutables
Semaine 2
Jour 5
- Les états Reactive et @ngrx/store
Quelques règles
- Ne pas hésiter à poser des questions !
- Ne pas couper la parole (même si on a la réponse :-D)
- Pause entre 10h30 et 11h00
- Du travail personnel est nécessaire !
Les outils nécessaire
- Webstorm, Sublime Text, etc.
- Terminal, iTerm
- NodeJS (nvm)
- NPM (installed with NodeJS)
Pourquoi Angular 2 ?
- Un peu d'histoire
- Standards du web
- Performances
- Environnement "Reactive"
- Open-source & travail d'équipe
Un peu d'histoire
Angular 1
- Première version : 2009
- Créer par Miško Hevery
- 1.3m développeur utilise la version 1.X
Angular 2
- Annoncée en 2014
- RC disponible en mai 2016
- Actuellement : 2.0.0-rc2
- Déjà 360k développeurs
- Utilisation des bonnes pratique AngularJS 1.X
Ok et ? sinon pouquoi Angular 2 ?
Standard du web
Performances
Small is beautiful
170k
56k
45k
Angular 2
beta
Angular 1
Angular 2
now
Fast is beautiful
- Lazy-loading
- Rendu très rapide (vs Angular 1)
- 2,5x plus rapide la première fois
- 4,2x plus rapide lors d'une mise à jour
Environnement "Reactive"
Open-source & travail d'équipe
Panorama
- Les principaux artefacts
- Comment démarrer une application
- Et plus en détail !?
Les principaux artefacts
- Module
- Composant
- Metadata
- Template
- Data Binding
- Service
- Directives
- Dependency Injec
Comment démarrer une application
- Importer le module bootstrap
- Importer votre composant
- Importer vos dépendances
- Appeler la méthode bootstrap en lui donnant le composant et les dépendances
import {bootstrap} from 'angular2/platform/browser';
import {ROUTER_PROVIDERS} from 'angular2/router';
import {AppComponent} from './app.component';
bootstrap(AppComponent, [
ROUTER_PROVIDERS
]);
Et plus en détail
- Utilise la syntaxe ES6
- Angular 2 utilise les modules pour découper leur code source
- Les modules exportent des bouts de code que d'autres modules peuvent importer
- TIPS : Garder les modules léger et spécialisés
Module
// In home.component.ts
export class HomeComponent { }
// In app.component.ts
import {HomeComponent} from './home/home.component';
Module
- Les composants sont des classes ES6
- Les providers sont injectés dans le constructeur
- Déclaration explicite des providers & directives
- Possibilité d'intercepter tous les évènements
- Les propriétés et méthodes du composant sont disponibles dans la vue
Composant
export class HomeComponent implements OnInit{
title: string = 'Home Page';
body: string = 'This is the about home body';
message: string;
constructor(private _stateService: StateService) { }
ngOnInit() {
this.message = this._stateService.getMessage();
}
updateMessage(m: string): void {
this._stateService.setMessage(m);
}
}
Composant
- Décore une classe ES6
- On peut attacher des metadatas avec les annotations/décorateurs de TypeScript (ES7?)
- Les décorateurs sont des fonctions
- Le plus utilisé : @Component()
- prend un objet de config avec le sélecteur, le template, les providers, les directives, les pipes et les styles
Metadata
@Component({
selector: 'home',
templateUrl: 'app/home/home.component.html'
})
export class HomeComponent{ }
Metadata @Component()
- Un template est écrit en HTML et définit le rendu d'un composant
- Les templates comprennent des "data-binding", d'autres composants et directives
- Angular 2 utilise les évènements DOM natifs
- Angular 2 utilise le shadow DOM
Template
Template
Template
@Component({
selector: 'experiment',
templateUrl: './experiment.detail.component.html',
styles: [`
.experiment {
cursor: pointer;
outline: 1px lightgray solid; padding: 5px;
margin: 5px;
}
`]
})
Template
@Component({
selector: 'experiment',
template: `
<div class="experiment" (click)="doExperiment()">
<h3>{{ experiment.name }}</h3>
<p>{{ experiment.description }}</p>
<p><strong>{{experiment.completed}}</strong></p>
</div>
`,
styles: [`
.experiment {
cursor: pointer;
outline: 1px lightgray solid; padding: 5px;
margin: 5px;
}
`]
})
- Permet de créer un échange de données entre le composant et le template
- Inclut : interpolation, le binding de propriété, d'évènement et le two-way binding (propriété + évènement)
Data-binding
Data-binding
Data-binding
<h1>{{title}}</h1>
<p>{{body}}</p>
<hr/>
<experiment *ngFor="#experiment of experiments"
[experiment]="experiment"></experiment>
<hr/>
<div>
<h2 class="text-error">Experiments: {{message}}</h2>
<form class="form-inline">
<input type="text"
[(ngModel)]="message" placeholder="Message">
<button type="submit" class="btn" (click)="updateMessage(message)">
Update Message
</button>
</form>
</div>
- Un service est une classe ES6
- Un service s'occupe d'une chose uniquement
- Embarque toute la logique business du composant
- Classe ES6 décorée avec @Injectable si on veut l'injecteur dans no service
Service
Service
import {Injectable} from 'angular2/core';
import {Experiment} from './experiment.model';
@Injectable()
export class ExperimentsService {
private experiments: Experiment[] = [];
getExperiments(): Experiment[] {
return this.experiments;
};
}
- Une directive est une classe ES6
- Décorée avec @Directive()
- Un composant est une directive avec un template !
- Directives disponibles nativement dans Angular 2
Directive
Directive
import { Directive, ElementRef } from 'angular2/core';
@Directive({
selector: '[femBlinker]'
})
export class FemBlinker {
constructor(element: ElementRef) {
let interval = setInterval(() => {
let color = element.nativeElement.style.color;
element.nativeElement.style.color =
(color === '' || color === 'black') ? 'red' : 'black';
}, 300);
setTimeout(() => {
clearInterval(interval);
}, 10000);
}
}
- Permet de récuperer l'instance d'une class par son nom (Singleton)
- Permet d'initialiser qu'une seule fois les services
- Pour utiliser DI pour un service, il faut l'enregistrer en tant que provider : au bootstrap de l'application ou dans les metadata d'un composant
Dependency Injection
Dependency Injection
// experiments.service.ts
import {Injectable} from 'angular2/core';
@Injectable()
export class ExperimentsService { }
// experiments.component.ts
import {ExperimentsService} from '../common/ experiments.service';
import {StateService} from '../common/state.service';
export class ExperimentsComponent {
constructor(
private _stateService: StateService,
private _experimentsService: ExperimentsService
) {}
}
- Regarde les changement dans le modèle de donnée pour recompiler le DOM
- Les changements sont : les évènements, les requêtes XHR et les timers
- Chaque composant possède son détecteur de changement
- On peut personnaliser le ChangeDetectionStrategy.OnPush pour utiliser des objets immutable ou observables
- On peut dire à Angular d'écouter un composant particulier en injectang ChangeDetectorRef et en appelant markForCheck() dans le composant
Détection de changement
Détection de changement
export interface Item {
id: number;
name: string;
description: string;
};
export interface AppStore {
items: Item[];
selectedItem: Item;
};
- Angular utilise Jasmine (framework de test)
- On doit :
- Importer les dépendances depuis @angular/testing
- Importer les classes à tester
- Inclure les providers en important beforeEachProviders
- Injecter les providers en appelant inject([arrayOfProviders], (providerAliases) => {})
Les tests
Les tests
import { describe, it, expect } from 'angular2/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
it('should be a function', () => {
expect(typeof AppComponent).toBe('function');
});
});
- Inclure tous les fichiers liés à un composant dans le même dossier
- CIA pour Class Import Anotate
- Utiliser des templates écrit dans le fichier JS
- Garde le template simple et court
- Déporter la logique métier du composant vers un provider
- Découper vos composants complexe
- Toujours réfléchir à comment les données vont être changer (impact sur le Change Detection)
Les conseils d'architecture
Défi
- Récupérer et faire tourner l'application
- Identifier les artefacts Angular
- Ajouter une propriété dans un composant et l'afficher dans la vue
- Ajouter une propriété dans le service stateService et l'utiliser dans un composant
- BONUS : Créer une interface pour typer votre propriété
Angular 2 Training - Day 1
By Benjamin LONGEARET
Angular 2 Training - Day 1
- 799