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

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