LE WEB DE DEMAIN ! C’EST DÉJÀ AUJOURD’HUI
Angular 2
Meetup N°2
24/09/2016
#ngMorocco
#ngMorocco
Ouadie Lahdioui
Consultant IT
lahdiouiouadie
ouadie-lahdioui
Pour vous servir ...
Regardez la présentation en temps réel : https://slides.com/ouadielahdioui/angular2/live
lahdiouiouadie
Bataille de pouces géante
Ce qu'on va voir !
Angular Universal
Module Loaders
Material design
Composantes
NativeScript
Angular CLI
TypeScript
Services
Zone.JS
Augury
Mobile
Pipes
Ce qu'on NE va pas voir !
Functional Reactive Programming
i18n (internationalization)
Change detection
WebWorkers
Observables
Animations
Routage
Tests
RxJS
Angular 2 has finally been released !
has finally been released!
Wake up
Avez-vous déjà utilisé Angular ?
Avez-vous un retour d'expérience
Sur Angular 1.x ?
Angular 1.x, Piqûre de rappel
Model-View-Whatever (a.k.a MV* )
Injection de dépendance
Liaison bidirectionnelle
Expressions
Directives
Services
Module
Filtres
Scope
...
Mais c'est quoi le problème avec Angular 1.x ?
l'injection de dépendance
function MyController($scope, $window) {}
someModule.controller(‘MyController’, [‘$scope’, function($scope) { }]);
MyController.$inject = [‘$scope’, ‘$window’];
Pour faire la minification !
Débogage
<div ng-repeat=”phone in user.phones”> {{ phone }} </div>
Impossible de faire un points d'arrêt dans {{ }}
C'est quoi la source du problème ?
C'est quoi le résultat si "user" est undefined ?
Le dirty checking
Le support d'une limite théorique de 2000 bindings/page web
Et la dégradation des performances
Héritage des scopes
<div ng-init="phone = 11"> {{ phone }} </div>
<div ng-if="true">
<button ng-click=”phone = 22">change phone</button>
</div>
<div ng-init="phone = {value: 11}"> {{ phone.value }} </div>
<div ng-if="true">
<button ng-click=”phone.value = 22">change phone</button>
</div>
C'est quoi la résultat si je clique sur "change phone" ?
Cas 1 :
Cas 2 :
Est la source de la plupart des problèmes
Search engine optimization
http://monsite.com/#/clients/edit
http://monsite.com/#/clients/send/2
Le moteur de recherche ne sait pas que ce sont deux pages différentes :
Pas d'évalution JS dans les robot d'indexation :
La complexité des DIRECTIVES
Trasnclude, Compile, Link, Controller ...
Tous les chemins mènent à Rome
You have a factory, wich is a service, and you have a service wich is a service, both have providers, and when you write a factory as your service, you actually write a provider wich returns a factory wich is basically A SERVICE
- Extrait de la session de Shai Reznik à ngConf
Pourquoi Angular 2 ?
Né pour résoudre une problèmatique
ONE TEAM + CORE COMPETENCE + ONE CODE BASE
=
LOTS OF STUFF
Multi platformes
WEB
MOBILE WEB
MOBILE natif
android - ios - windows
desktop
windows - mac - linux
HTTP 2
VM Turns
Push Notification
Zones
DI
intellisense
CLI
Débogage
Putting the pieces together
Server rendering
Isomorphique
Mobile
le fruit d'un effort communautaire
... D'un framwork à une plateforme
Angular 1.x
Angular 2
Angular 2, le renouveau
Popularité d'Angular selon libscore.com
Evolution de l'intérêt de recherche
Feedback sur Stack Overflow
Source : Keynote ng-conf 2016
Taille de la communauté
RIP
Il était une fois dans angular 1 ...
PREMIÈRE IMPRESSION DE LA COMMUNAUTÉ
WHAT ! Et mes web apps Angular 1.x ?
-Brad Green, Engineering director at Google and AngularJS team manager
Angular 1 will continue to receive bugfix and security patch support for 18-24 months after the release of version 2.0.
Concepts-clés
TypeScript
Source code : *.ts
Source code : *.js
Transpiling
interface Pokemon {
name: string;
size: string;
}
POO - typage statique - ANNOTATIONS
class Player {
fullName: string;
constructor(name: string, pokemon: pokemon) {
this.name = name;
this.pokemons.push(pokemon);
}
}
class PokemonBall() {
open() {...}
close() {...}
}
var sacha = new Player("Sacha", pikachu);
vue globale de l'architecture angular 2
Modularité
Modularité
- Minimiser les risques d'interaction involontaire avec l'extérieur
- Rendre les bibliothèques :
- Plus faciles à maintenir
- Mieux structurées
function getPlayer(){
return this.player;
}
function getBall(){
return this.ball;
}
module.exports = {
player: getPlayer,
ball: getBall
};
var pokemon = require('./pokemon.js');
console.log(pokemon.player());
console.log(pokemon.ball());
Exporter
Modularité avant l'ES 6
define(
['pokemonPlayer','pokemonBall'],
function(player, ball
) {
// Use player and ball
return myFunction;
});
var player = require('pokemonPlayer');
var ball = require('pokemonBall');
// use player and ball
module.exports = myFunction;
Deux écoles ont vu le jour grace à la communauté
CommonJS
AMD
modularité à l'aire de l'ES 6
En fin, ce pattern d'écriture modulaire est intégré dans le langage lui-même
export const maxAge = this.maxAge;
export function player() {
return this.player;
}
export function ball() {
return this.ball;
}
import { player, ball } from 'pokemon';
console.log(player());
console.log(ball());
Exporter
modularité avec angular 2
SystemJS : Un chargeur de modules universel pour JavaScript
AMD
(Asynchronous Module Definition)
CJS
(CommonJS)
REGISTER
(System.register)
ESM
(ECMAScript Module)
GLOBAL
(Global shim module format)
qu'est qu'un module peut exporter ?
// app/app.component.ts
export class AppComponent { }
// app/main.ts
import { AppComponent } from './app.component';
import { Directive } from '@angular/core';
@Directive({ selector: '[pokemon]' })
export class PokemonDirective { /*...*/ }
export class Logger {
log(msg: any) { /*...*/ }
error(msg: any) { /*...*/ }
}
Composantes
Le respect des nouveaux standards du web
Sans Composant
AVEC Composant
import { Component } from '@angular/core';
@Component({
selector: 'pokemon'
template: `...`
})
export class Pokemon implements OnInit {
ngOnInit() {
/* ... */
}
}
Déclaration d'un composant
OnChanges
OnInit
DoCheck
AfterContentInit
AfterContentChecked
AfterViewChecked
AfterViewInit
OnDestroy
Le cycle de vie d'un composant :
<ul>
<li *ngFor="let pokemon of pokemons">
<img src="/assets/pokemons/{{pokemon.id}}.png">
<p>{{pokemon.name}}</p>
<p>{{pokemon.category}}</p>
<img src="/assets/pokemons/{{pokemon.id}}.png">
<p>{{pokemon.description}}</p>
</li>
<ul>
Template d'un composant
arbre de composants imbriqués
Composant
principal
Composant
PokemonList
Composant
Navbar
Composant
SideBar
Composant 5
Composant
PokemonDetail
Application Angular 2
metadata d'un composant
@Component({
selector: 'pokemon-list',
templateUrl: 'app/pekemon-list.component.html',
directives: [PekemonDetailComponent],
providers: [PokemonService]
})
export class PokemonListComponent implements OnInit {
/* . . . */
}
liaison de données (a.k.a Data binding)
<p>{{pokemon.name}}</p>
<pokemon-detail [pokemon]="selectedPokemon"></pokemon-detail>
<button (click)="selectPokemon(pokemon)"></button>
[()] BANANA IN A BOX
43 Directives dans Angular 1 VS [()] dans Angular 2
= "value"
<input [(ngModel)]="pokemon.name">
Directives
1/ Composants :
2/ Directives structurelles :
3/ Directives attributs :
Une directive avec son sélecteur et son template
Agissent sur le DOM en ajoutant/retirant des éléments
Changent l’apparence ou le comportement d’un élément
<pokemon-detail></pokemon-detail>
<div [ngStyle]="setStyles()">
This div is italic, normal weight, and extra large (24px).
</div>
<div *ngIf="isPokemon">{{pokemon}}</div>
<div *ngFor="let pokemon of pokemons">{{pokemon}}</div>
Services
@Injectable()
export class PokemonService {
getPokemonById(id: number): Pokemon {
return this.pokemons.filter(pokemon => pokemon.id === id).pop();
}
}
PIPES
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'sample' })
export class SamplePipe implements PipeTransform {
transform(input: string): string {
return `${input} from sample pipe`;
}
}
UpperCasePipe - LowerCasePipe - CurrencyPipe - PercentPipe - DatePipe
...
- Effectuer des transformations directement dans le template :
<p>The hero's birthday is {{ birthday | date:'fullDate' | uppercase}}</p>
Injection de dépendances
constructor(private service: PokemonService) { }
PROVIDERS pour guider l'injector
import { Component } from '@angular/core';
@Component({
selector: 'home',
providers: [ PokemonService ]
})
export class HomeComponent {}
@NgModule({
declarations: [AppComponent, PokemonListComponent],
providers: [MdIconRegistry],
bootstrap: [AppComponent]
})
export class AppModule { }
Déclaration globale d'un provider au moment du bootstrap :
Déclaration locale d'un provider dans le composant :
L'injector crée un service à partir d'un objet moule : Provider
ZONE.JS
Monkey-patch des fonctions asynchrones
Zone.JS
- Similaire aux domains dans NodeJS et ThreadLocal dans Java
- l'implémentation des Zones inspirée par "Dart language"
A Zone is an execution context that persists across async tasks.
Async JavaScript
start()
showBulbasaur()
setTimeout(showPikachu, 0);
setTimeout(showCharmander, 0);
showSnorlax()
stop()
Temps
Temps
showCharmander
Queue :
Et si on veut savoir le temps d'execution ?
showBulbasaur()
setTimeout(showPikachu, 0);
setTimeout(showCharmander, 0);
showSnorlax()
Temps
showPikachu
(async)
(async)
Temps
(exclu)
(exclu)
ASYNC JavaScript avec Zone.js
Temps
showBulbasaur()
showSnorlax()
showPikachu()
showCharmander()
start()
stop()
start()
stop()
start()
stop()
showBulbasaur()
showSnorlax()
showPikachu()
showCharmander()
onZoneEnter()
onZoneEnter()
onZoneEnter()
onZoneLeave()
onZoneLeave()
onZoneLeave()
- Exécute du code avant et après
- Testing / Timing / Gestion des erreurs / ...
- Un jour, ça vas devenir un standard (Ecma TC39)
ZONE.JS
Zone.current.fork({}).run(function () {
Zone.current.inTheZone = true;
setTimeout(function () {
console.log('in the zone: ' + !!Zone.current.inTheZone);
}, 0);
});
console.log('in the zone: ' + !!Zone.current.inTheZone);
/* OutPut */
'in the zone: false'
'in the zone: true'
RENDERS
Renderers
- Remplaçable selon l'environnement
- Précompilation (taille de l'app + temps de bootstrap)
Server side render
Angular universal
Angular Mobile Toolkit
Progressive web apps :
Instant loading
Offline
Installable
Notifications
App natives
NativeScript
- Un framework JavaScript opensource pour créer des applications mobiles natives (pas de WebView)
- Basé sur une machine virtuelle JS (eg: JavaScriptCore, V8, ...)
var myAlert = new UIAlertView();
myAlert.message = "NativeScript rocks!";
myAlert.show();
qu'est ce que je peux faire avec ?
MATERIAL DESIGN
Le web design selon Google
Material design
Angular material 1
Angular material 2
Angular-CLI
Angular Augury
Style Guide
Officiel et communautaire
Migration
Angular 1.x -----------> Angular 2
It's really hard for us to build a bridge to a city that doesn't exist yet.
- Brad Green
Solution N° 1
sudo rm -rf yourAngularProject
commencez par :
- Lire le Styleguide
- Adopter une approche composants
- Utiliser TypeScript
- Utiliser un module loader
- Utiliser un adapteur
Déja en PRODUCTION
Capital One
Lucidchart
Kiva
Fidelity
... we must find a fine balance between supporting and improving the existing Angular, while building the best Angular yet. ... This is why I need you to step up ! Help each other. Help us triage issues and review pull requests. Answer questions on the mailing list, stackoverflow etc.
- Igor Minar, Lead on the Angular project
STEP UP WITH US
POUR ALLER PLUS LOIN
- Le site officiel Angular.io
- Awesome Angular 2 - Angular Class
- Getting started with Angular 2 - Wassim Chegham
- Creating Cross-Platform Apps with Angular 2 @ Microsoft Build - Brad Green
- Angular 2 and the future of HTML5 apps @ Fluent conf - Brad Green
N'oubliez pas de partager avec moi vos feedbacks sur Angular 2 !
lahdiouiouadie
ouadie-lahdioui
Merci !
lahdiouiouadie
Angular 2
By Ouadie LAHDIOUI
Angular 2
Le web de demain ! c'est déjà aujourd'hui
- 1,739