Angular 2

Le reveil de la force

#BzhCmp #Ng2BzhCmp

BreizhCamp 2015

#BzhCmp

BreizhCamp 2015

#BzhCmp

Nicolas Pennec

Full-Stack Web Developer

Co-Fondateur de @RennesJS

#Ng2BzhCmp #BzhCmp

BreizhCamp 2015

#BzhCmp

Grégory Houllier

Architecte Web, passionné par le Front-End

Co-Fondateur de @RennesJS

#Ng2BzhCmp #BzhCmp

#Ng2BzhCmp #BzhCmp

Meetup le dernier jeudi de chaque mois

25/06/2015 à Epitech

Angular 1.X

#Ng2BzhCmp #BzhCmp

  • Framework JS MV*
  • Projet open-source porté par Google
  • Version 1.X très populaire, 1er sur GitHub (39K stars)
  • Concepts :
    • Orienté Single Page Application (SPA)
    • Étendre le langage HTML (directives)
    • Data Binding bi-directionnel
    • Dependency Injection, $scope, ...

Annonce d'Angular 2

#Ng2BzhCmp #BzhCmp

Octobre 2014:

  • Première annonce
  • Rupture de concepts
  • Pas de rétrocompatibilité
  • Nouveau langage (AtScript)

Annonce d'Angular 2

#Ng2BzhCmp #BzhCmp

Mars 2015

  • Rétropédalage de Google
  • Opération séduction des devs
  • Roadmap de la branche 1.X
  • Nouveau langage (TypeScript)

Philosophie

#Ng2BzhCmp #BzhCmp

  • Apprendre des erreurs d’Angular 1
    • 2-way data binding, dirty-checking, $scope, ...
  • Se baser sur les futurs standards du web

    • WebComponents

    • ES6 / ES7 / TypeScript*

    • EverGreen Browsers

  • Emulation due à la concurrence React et Ember
    • ​Amélioration des performances

ES6, ES7, TypeScript

#Ng2BzhCmp #BzhCmp

ES5

ES6

ES7

TS

#Ng2BzhCmp #BzhCmp

  • Surcouche à ES6/ES7
  • Créé par Microsoft
  • Collaboration avec Google
    • Merge avec AtScript
  • Actuellement en version 1.5-beta

Exemple TypeScript

#Ng2BzhCmp #BzhCmp

import { Annotation } from 'angular2/angular2';
import { Api as ApiSpeakers } from './api/speakers';

@Annotation({
  property: 'value'
})
class Talk {

  speakers: Array<String>;
  thread: String;

  constructor(thread: String, api: ApiSpeakers) {
    this.thread = thread;
    api.get().then((speakers) => {
      this.speakers = speakers;
    });
  }
}

TS

Production Ready ?

#Ng2BzhCmp #BzhCmp

NO!

Production Ready ?

#Ng2BzhCmp #BzhCmp

  • Version Alpha "Developer Preview"

  • Solution instable

  • API changeante

  • Documentation en cours

  • Pas de Roadmap

PoC Ready ?

#Ng2BzhCmp #BzhCmp

YES!

BreizhCamp 2015

Ce qui va changer ?

#Ng2BzhCmp #BzhCmp

Angular 1

  • Controller
  • Service
  • Module
  • $scope
  • jQlite
  • Directive
  • Dependency Injection

Angular 2

  • Controller
  • Service
  • Module
  • $scope
  • jQlite
  • Directive
  • Dependency Injection (TypeScript)
  • Component
  • Classes (ES6)

BreizhCamp 2015

#BzhCmp

Directives/Components

#Ng2BzhCmp #BzhCmp

Directives Angular 1.X

Directives Angular 2.X

Components Angular 2.X

Etendre le DOM

Encapsule un template

BreizhCamp 2015

#BzhCmp

A quoi ça va ressembler?

#Ng2BzhCmp #BzhCmp

BreizhCamp 2015

#BzhCmp

Bootstrap your code

#Ng2BzhCmp #BzhCmp

<!DOCTYPE html>
<html>
 <head>
   <title>Angular 2 - BreizhCamp</title>
   <script src="//github.jspm.io/jmcriffey/bower-traceur-runtime@0.0.90/traceur-runtime.js"></script>
   <script src="//jspm.io/system@0.16.js"></script>
   <script src="//code.angularjs.org/2.0.0-alpha.23/angular2.dev.js"></script>    
 </head>
 <body>
   <my-component></my-component>
   <script type="module">
     import { bootstrap } from 'angular2/angular2';
     import { MyComponent } from 'app/my-component';

     bootstrap(MyComponent);
   </script>   
 </body>
</html>

HTML

BreizhCamp 2015

#BzhCmp

Component (1/3)

#Ng2BzhCmp #BzhCmp


<my-component></my-component>
import {
  Component, View
} from 'angular2/angular2';

@Component({
  selector: 'my-component'
})
@View({
  template:
    '<div>Hello, BreizhCamp</div>'
})
export class MyComponent {

}

HTML

TS

BreizhCamp 2015

#BzhCmp

Component (2/3)

#Ng2BzhCmp #BzhCmp

import {
  Component, View
} from 'angular2/angular2';

@Component({
  selector: 'my-component'
})
@View({
  template:
    '<div>Hello, {{message}}</div>'
})
export class MyComponent {
  constructor() {
    this.message = 'BreizhCamp';
  }
}

<my-component></my-component>

HTML

TS

BreizhCamp 2015

#BzhCmp

Component (3/3)

#Ng2BzhCmp #BzhCmp

import {
  Component, View
} from 'angular2/angular2';

@Component({
  selector: 'my-component',
  properties: {
    message: 'msg'
  }
})
@View({
  template:
    '<div>Hello, {{message}}</div>'
})
export class MyComponent {
}

<my-component msg="BreizhCamp">
</my-component>

HTML

TS

BreizhCamp 2015

#BzhCmp

Directive (1/2)

#Ng2BzhCmp #BzhCmp

import {
  Directive
} from 'angular2/angular2';

@Directive({
  selector: '[tooltip]',
  properties: {
    text: 'tooltip'
  },
  hostListeners: {
    mouseover: 'display()'
  }
})
export class Tooltip {
  display() {
    console.log(this.text);
  }
}

<div tooltip="Hello BreizhCamp">
  Hover Me!
</div>

HTML

TS

BreizhCamp 2015

#BzhCmp

Directive (2/2)

#Ng2BzhCmp #BzhCmp

import {
  Component, View
} from 'angular2/angular2';
import { Tooltip } from './tooltip';

@Component({
  selector: 'my-component',
  properties: {
    message: 'msg'
  }
})
@View({
  template:
    '<div tooltip="Yo!">Hi, {{message}}</div>',
  directives: [Tooltip]
})
export class MyComponent {}

<my-component msg="BreizhCamp">
</my-component>

HTML

TS

Templating (1/2)

#Ng2BzhCmp #BzhCmp

<div>Hello, {{username}}</div>
<button [model]="message" (click)="hello(message)">
  Click Me!!
</button>
<audio-player #player></audio-player>
<button (click)="player.pause()">Pause</button>

Interpolation

Property binding / Event binding

Local variable (référence)

Templating (2/2)

#Ng2BzhCmp #BzhCmp

<div *if="user">Hello, {{user.name}}</div>

// Équivalent à

<template if="user">
  <div>Hello, {{user.name}}</div>
</template>
<ul *if="list.length">
  <li *for="#item of list">
    {{item.title}}
  </li>
</ul>

Whole template

BreizhCamp 2015

#BzhCmp

Dependency Injection

#Ng2BzhCmp #BzhCmp

import { MyService } from './my-service';

@Component({
  selector: 'my-component',
  injectables: [MyService]
})
@View({
  templateUrl: '/path/to/my-component.html'
})
class MyComponent {
  myService: MyService;

  constructor(myService: MyService) {
    this.myService = myService;
  }
  fetchData() {
    this.myService.get().then((list) => {
      console.log(list);
    });
  }
}

BreizhCamp 2015

#BzhCmp

Migration 1.X vers 2.X ?

#Ng2BzhCmp #BzhCmp

Pas de rétrocompatibilité

Mais comment anticiper ces changements?

  • Classes ES6/TS pour la définition des services
  • Modules ES6 pour structurer son code
  • Utiliser le ngNewRouter qui est sera disponible en 1.4 1.5
  • Préférer la syntaxe "controllerAs" et "bindToController" pour les directives

Documentation

#Ng2BzhCmp #BzhCmp

Ressources

#Ng2BzhCmp #BzhCmp

Conclusion

#Ng2BzhCmp #BzhCmp

Angular 2 c'est comme le prochain Star Wars

tout le monde l'attend, mais personne ne sait si ça sera à la hauteur

BreizhCamp 2015

#BzhCmp

#Ng2BzhCmp #BzhCmp