What I've learned after reading...

#BDXIO17

Emmanuel DEMEY
       Zenika Lille
      EmmanuelDemey

Décorateurs

Fetch

Metadata Reflection API

@angular/cli

ECMAScript 2015

Shadow DOM

PWA

Custom Elements

DOM

Zones

 

Intl

WebWorkers

Intl
async

decorators

zones

Intl API

Internationalization API

Manipuler une donnée en fonction d'une locale

 

  • Collator
  • NumberFormat
  • DateTimeFormat
  • PluralRules

Internationalization API

new Intl.Collator(locale, options)
String.prototype.localeCompare(locale, options)
new Intl.DateTimeFormat(locale, options)
Date.prototype.toLocaleString(locale, options)
Date.prototype.toLocaleDateString(locale, options)
Date.prototype.toLocaleTimeString(locale, options)
new Intl.NumberFormat(locale, options)
Number.prototype.toLocaleString(locale, options)

DateTimeFormat

let formatter = new Intl.DateTimeFormat(“en”,{});
formatter.format(new Date(Date.UTC(2017,11,25,3,0,0)))

let formatter = new Intl.DateTimeFormat(“fr”,{
    month: “long”
    day: “numeric”, /* 2-digit */     
    year: “numeric”, /* 2-digit */    
    hour: “numeric”, /* 2-digit */
    minute: “numeric”, /* 2-digit */     
});
formatter.format(new Date(Date.UTC(2016,10,10,3,0,0)));

12/25/2017

25/12/2017

décembre

25 décembre 2017

25 décembre 2017 04h

25 décembre 2017 04h00

NumberFormat


let formatter = new Intl.NumberFormat(“en”,{});
formatter.format(1000.59)

let formatter = new Intl.NumberFormat(“fr”,{
    style: “currency”, /* percent, number */
    currency: “EUR”, /* USD */
    currencyDisplay: “name”, /* symbol */
    useGrouping: false,
    maximumFractionDigits: 1
});

formatter.format(1000.57);

1,000.59

1 000,59

1 000,59 euros

1000,59 euros

1000,6 euros

Vous avez dit        ?

@Pipe({name:”number”}) 
class NumberPipe { }

@Pipe({name:”percent”}) 
class PercentPipe { }

@Pipe({name:”currency”}) 
class CurrencyPipe { }

@Pipe({name:”date”}) 
class DatePipe { }

Vous avez dit        ?

{{ price | currency:”EUR”:true:4.2-2 }}

Mettons nos mains dans le cambouis

Mauvaise Nouvelle...

Mauvaise Nouvelle...

  • Nouvelle implémentation en Angular 5.x
  • Nombreux Bugs avec l'implémentation Intl
  • Attention potentiels breaking changes
  • Anciennes versions toujours disponibles (pout l'instant)
 import { NgModule } from '@angular/core';
 import { CommonModule, DeprecatedI18NPipesModule } 
    from '@angular/common';

 @NgModule({
    imports: [
        CommonModule,
        // import deprecated module after
        DeprecatedI18NPipesModule
    ]
})
export class AppModule { }

Async

@Component({
   template: `{{ user }}`
})
export class AppComponent {
    
    user: string;

    constructor(private httpClient: HttpClient){
        httpClient.get('/api/data')
            .subscribe(data => this.user = data);
    }
}
@Component({
   template: `̀{{ user$ | async }}`
})
export class AppComponent {
    
    user$: Observable<string>;

    constructor(private httpClient: HttpClient){
        this.user$ = httpClient.get('/api/data');
    }
}
@Pipe({
    name: 'async',
    pure: false
})
export class AsyncPipe {

}

Pipe impure

Mettons nos mains dans le cambouis

Decorators

Les décorateurs

Fonctions pour ajouter des métadonnées à des objets JS (Property, Method, Class, Parameter...)

Les décorateurs

@Input
public props: string;


function Input( … ){
}

Les Factories

@Input(“inputName”)
public props: string;


function Input(inputName){
   return function(...) { }
}

Les différentes signatures

declare type ClassDecorator = (target: Function) => Function 
declare type PropertyDecorator = 
          (target: Object, propertyKey: string) => void; 
declare type MethodDecorator = 
          (target: Object, propertyKey: string, descriptor:       
          TypedPropertyDescriptor) => TypedPropertyDescriptor;
declare type ParameterDecorator = 
          (target: Function, propertyKey: string, 
          parameterIndex: number) => void;

Mon 1e décorateur

@log sayHello(){ … }

function log(target,key,descriptor){
    let orig = descriptor.value;
    descriptor.value = function(...args){ 
        console.log(“function called”);
        return orig.apply(this, args);
    }
    return descriptor;
}

Mon 2e décorateur

@Injectable
class DevFestService {
   constructor(service: Service) { }
}

function Injectable(target){
  let original = target;
  let newC = function(...args){
     args = args.map(s => injector.get(s));
     return original.apply(this, args);
  }
  newC.prototype = original.prototype; 

  return newC;
}

Oui..., mais au Runtime ? 

var __decorate = function () { … };
function Injectable(target) { … }

var DevFestService = (function () {
    function DevFestService() {...}
    DevFestService = __decorate([
        Injectable
    ], DevFestService);
    return DevFestService;
}());

Vous avez dit        ?

  • Définir les éléments Angular2

  • Injection de Dépendances

  • Créer des Inputs / Outputs

  • Accéder aux éléments HTML

  • Intéragir avec l’élément host

Vous avez dit        ?

//<button click-handler>Click Me</button>

@Directive({ selector: ‘[click-handler]’})
export class ClickHandler {
   @Input() parameter: string;
   constructor(@Inject(LOCALE_ID) locale) {}
 
   @HostBinding(‘click’)
   click(){ … }
}

Les Zones

startTimer()
goToBdx();
setTimeout( _ => {
	veryLongTask()
}, 0);
setTimeout( _ => {
	veryLongTask()  
}, 0);
goBackToLille();
endTimer()

Hooks for the Event Loop

Création d'une Zone

zone.fork( specConfig )
   .run(function(){ 
	...
   });


ZoneSpec

interface ZoneSpec {
   onScheduleTask: () => {},
   onInvokeTask: () => {},
   onHandleError: () => {},
   onHasTask: () => {}
}

Monkey Patch

window.setTimeout = function(c, time){
    Zone.current.onScheduleTask();
    setTimeout(function(){
	Zone.current.onInvokeTask();
        try {
           c(); 
        } catch (e){
           Zone.current.onHandleError()
       }
    }, time);
}

Vous avez dit        ?

  • Change Detection
  • StackTraces complètes

Vous avez dit        ?

Désactivation des zones : 

  • Animations

  • Analytics

  • Evénements trop fréquents

Vous avez dit        ?

class AnalyticsService {
    constructor(
        private zone:NgZone,
        private http: HttpClient){
    }

    sendToAnalitics(){
        this.zone.runOutsideAngular(() => {
            this.http.post(“/api/analytics”, {})
                .subscribe(...);
        });
    }
}

Emmanuel DEMEY
       Zenika Lille
      EmmanuelDemey

Noun Project
https://thenounproject.com/

Copy of deck

By Emmanuel Demey

Copy of deck

  • 1,746