Découverte

DU FramEwork JavaScript

ANGULAR 7

Par Loïc TRUCHOT

What, When & WhY

  • SPA framework
  • routeur, ajax, seo, langues, formulaires, transformation
  • targets :
    • browser (app/element)
    • server (Universal)
    • mobile (PWA & Ionic)
    • OS (Electron)
  • VS React ? VS Vue ?
  • Learning curve ↗↘⇗

Versioning 

  • AngularJS vs Angular (2+)
  • dirty checking vs zone.js
  • tous les 6 mois
  • 7 -> octobre 2018
  • 8 -> avril 2019
  • le prix de la stabilité
  • semantic versioning :
    • majeur.mineur.patch
  • ng update
  • https://update.angular.io/

PRéREQUIS

  • Node.js (8+) & NPM (6+)
  • ES6+ (const/let, import/export, =>, ..., `bla ${bla}`) 
  • TypeScript (types, decorators, POO avancée, config)
  • RxJS (Observable, subscribe, pipe, map)
  • Webpack

Une SPA en 5 minutes

node -v && npm -v 

npm install -g @angular/cli
ng -v

ng new pizza-yolo
cd pizza-yolo
ng serve

Utiliser un simple terminal

Command Line Interface (ng), utile pour :

  • créer un nouveau projet
  • créer une partie de projet (component, service, etc.)
  • lancer le projet en dev, ou builder pour le web
  • tester, linter, réutiliser, mettre à jour, etc.
vérifier la version de node
installer le CLI
créer un nouveau projet
et le lancer sur http://localhost:4200

l'arborescence d'un projet

  • .git et .gitignore pour la gestion de version
  • e2e/karma/protractor pour les tests
  • .angular-cli.json pour la configuration du CLI
  • .editorconfig, tslint, tsconfig pour les règles de code
  • package.json (+lock) et node_modules pour les dépendances
  • README pour décrire le projet
  • src pour les sources du projet

 

  • index.html pour la racine HTML
  • assets pour les fichiers statiques
  • environments pour varier les configs
  • favicon.ico pour l'apparence dans la barre de nav
  • styles.css pour les styles globaux
  • test.ts pour les tests
  • tsconfig et typings pour aider à compiler
  • polyfills.ts pour la rétrocompatibilité
  • main.ts pour la racine de l'arbre (code)
  • app pour le tronc et les branches (code)

l'arborescence d'un projet

  • AppModule, module racine contenant 
    • d'autres modules
    • des « services »
    • des « components » contenant 
      • des « controllers »
      • des « templates » contenant  
        • des « directives »

Dans les sources... un arbre

WORKSHOP SESSION

AMELIORER SON ENVIRONNEMENT DE TRAVAIL

VS Code

  • ext.: prettier, tslint, ALS
  • tslint + codelyzer + rxjs-tslint
  • "prettier.tslintIntegration": true
  • "editor.formatOnSave": true

Sublime text

  • packages: Typescript, SublimeLinter, SublimeLinter-tslint, JsPrettier
  • npm: prettier + tslint-config-prettier, à ajouter à l'extends du tslint
  • "auto_format_on_save": true
  • potentiellement un peu bogué

WORKSHOP SESSION COMPONENT

un menu pour ma pizzeria

  • retirer le contenu d'origine, sauf le H1
  • remplacer titre par nom de pizzeria, sans toucher  HTML
  • ajouter array « menu » dans  controller, avec vos pizzas
  • ajouter bouton "voir le menu"
  • (click) pour afficher menu
  • *ngIf pour montrer ou cacher le menu
  • *ngFor pour répéter les éléments du menu
  • ajouter un bouton "passer la commande", qui reste disabled  grace à la propriété « pristine »  du controller
  • ajouter la feuille de style de bootstap 4 à l'index.html

A RETENIR

  • Application Angular =
    • arbre de components
  • Component =
    • un controller, la  class  TypeScript du component
    • un template, le HTML du component
    • éventuellement une feuille de style du component
  • Controller: propriétés et méthodes que le HTML utilise
  • Template:  HTML + directives d'angular (*ngIf, *ngFor...) et « syntactic sugar » :
    • {{ title }}: du JS dans le texte
    • (click): du JS dans les évènements utilisateurs
    • [disabled]: du JS dans les attributs HTML

WORKSHOP SESSION

Une banane dans une boite

  • ajouter un input de texte pour le nom du client, et une propriété « nom » dans le controller
  • montrer grâce à [(ngModel)] et {{ nom }} que le nom change en direct
  • faire en sorte que, tant que le nom est vide, passer la commande reste « disabled »
  • faire en sorte que chaque pizza soit détaillée (avec photo) et s'ajoute à un panier au click
  • faire en sorte que, tant que le panier est vide, passer la commande reste « disabled »
  • permettre la suppression d'une pizza du panier
  • donner un prix à chaque pizza: présenter le total à côté du bouton de commande

A RETENIR

  • two-way-binding = event + update = [()]
  • utiliser le CLI =
    • ng new = nouveau projet
    • ng serve = lancer dans le navigateur et watcher le code
  • Les directives natives d'Angular sont  précédées de « ng »
  • app-root est le component unique à la racine de l'arbre
  • Comprendre la différence entre attribut HTML et propriété du DOM
  • Usage des « pipes » dans le template ( | json, | currency, etc.)

WORKSHOP SESSION

REFACTO TIME !

  • Faire de l'Array de pizza un fichier à part, grâce à l'import-export
  • Ajouter volontairement une pizza erronée
  • Générer un component pizza grâce au CLI
  • Afficher chaque pizza grâce à ce nouveau component, en donnant les infos grâce à un [propriété] et un @Input
  • S'assurer que son code est parfait : commentaires, sauts de ligne, nom des variables
  • Relire le code ensemble

A RETENIR

 

  • L'import/export permet d'alléger les fichiers et d'organiser son code
  • Comprendre x2 la différence entre attribut HTML et propriété du DOM
  • Comprendre le Safe Navigation Operator « obj?.prop »
  • utiliser le CLI =
    • ng generate component <nom-du-cpnt> = créer un nouveau component
  • Chaque component peut-être utilisé en tant que directive dans le HTML autant de fois qu'on veut (exemple : <app-button></app-button>). 
  • ATTENTION: pour pouvoir utiliser ce component, il faut le déclarer dans le module

PUSH NOTRE OEUVRE 

SUR GITHUB

  • Sauvegarde
  • Gestion de version
  • Travail d'équipe
  • Intégration continue
git config user.email "monemailgithub@gmail.com"
git config user.name "Prénom Nom"

git remote add origin https://github.com/login/repo.git

git add .

git commit -m "Mon message qui restera dans l'historique"

git push -u origin master
mes infos de committer
ajouter tous les fichiers
sauver l'état, avec un msg
Créer un nouveau répertoire sur github, puis...
envoyer sur github
  • Open source
  • Porte-folio
  • Microsoft...
associer projet au repo

Digression sur les classes...

WORKSHOP SESSION

Service compris...

  • générer un nouveau service pour notre panier et nos pizza, avec ng generate service data
  • charger le service dans l'appModule et les components qui en ont besoins
  • prévoir un objet partagé qui contient les pizzas par quantité
  • associer les méthodes d'ajouts et de suppression de pizza au service
  • faire des boutons + et - pour changer les quantités des pizzas
  • Tout dois marcher comme avant, mieux qu'avant !

A RETENIR

  • Pourquoi un service ?
    • data et logique partagée entre component
    • lisibilité et testabilité des components
    • réutilisation entre projet
  • Comment le créer ?
    • ng g s <nom-du-servise>
    • provider dans l'app-module, ou « provideIn: "root" »
    • injecter dans le component 
    • Attention: ne pas provider à plusieurs endroits de l'app si on veut un Singleton.

Digression sur le Routing client

WORKSHOP SESSION

chemins et ROUTES

  • Créer un module de routing
  • Créer un component pour l'accueil, un autre pour la commande
  • Ajouter un directive de <router-outlet></router-outlet> à l'app component
  • Ajouter les routes "/accueil" et "/commande" au routeur
  • Placer le contenu de la home dans le bon component
  • Créer un résumé de la commande dans le component de commande
  • Ajouter le champ de nom,  un tel, un mail, une adresse et un bouton d'achat au component de commande
  • Ajouter un lien vers la commande dans la home, et vice-versa

A RETENIR

  • Le routeur permet d'organiser la navigation (les URL) côté client
  • le routeur est généré en même temps que l'app, ou ajouté après :
    • ng generate module --routing=true
  • la directive <router-outlet></router-outlet> contiendra les component affiché ou non selon la route
  • la configuration du chaque route peut se faire dans le module de routing, un associant un « path » à un « component »
  • des liens entre component sont faits avec la propriété <a routerLink="/url">

WORKSHOP SESSION

ERREUR 404, Slide not found

  • ajouter une redirection de l'URL racine « /» vers l'accueil
  • ajouter une redirection des URL inconnus vers un component « not-found »
  • ajouter un component de « charte qualité » de la pizzeria, et un menu dont l'url courante est mise en évidence
  • prévoir un « empty state » pour la page de commande
  • prévoir une page spéciale pour afficher le détail d'une pizza, qui change selon l'id

Digression sur aJAX, le serveur ET le CRUD

WORKSHOP SESSION

SERVICE angular et REQUÊTES Ajax

  • Mettre nos data d'origine dans un JSON Server
    • npm install -g json-server
    • créer fichier db.json avec nos data
    • json-server --watch db.json
  • importer le HttpClientModule dans l'AppModule
  • injecter le HttpClient dans notre data service
  • Faire une requête get pour retrouver toutes les pizzas
  • utiliser le | async pour les présenter
  • utiliser la méthode d'Observable « pipe » pour transformer les données (faire un discount de 20% sur les prix)
  • Comparer avec .subscribe()
  • Faire une requête get pour retrouver une seule pizzas

A RETENIR

  • Angular propose des modules optionnels, comme le HttpClientModule pour faire de l'Ajax
  • Il suffit le l'importer dans l'AppModule pour pouvoir utiliser l'un de ses services, le HttpClient
  • Les méthode du HttpClient retournent des Observables, qu'on déclenche grâce à | async dans le template ou .subscribe() dans le controller
  • Grâce à .pipe(), on peut modifier les données d'une Observable

Digression sur les FORMULAIRES...

WORKSHOP SESSION

Helpers et pipes : réutiliser ses outils

  • Dans le component de commande, ajouter un champ pour le numéro de carte
  • Prévoir son formatage automatique grâce à un pipe
  • Créer un champ « commentaire »
  • Faire en sorte que tous les champs soient requis, sauf commentaire
  • Prévoir des messages spéciaux si le champs sont requis. 
  • Prévoir une validation de l'email avec un message spécial
  • Prévoir une action de « submit » pour le formulaire
  • Prévoir une requête POST qui envoie la commande au serveur
  • Prévoir un message pour la commande validée, ou en cas d'erreur
  • environment ?
  • provide service (in root, or elsewhere)
  • | async & ngOnChange or share subject ?
  • build-in pipes (date, upper/lowercase, percent, etc.)
  • Do we need some guards ?

STOP ! REFACTO TIME !

And (RE-)discovering MODULES

  • module
  • ng g m
  • rearrange folders + paths @alias
  • declaration
  • imports
  • exports
  • providers
  •  lazy loading

LIVE CODING SESSION

DISCOVERING FORMS

  • ngForm
  • reactive forms

WORKSHOP SESSION

Add A CREATE/EDIT FORM

  • Add somewhere a "create new", that navigate to edit-quizz
  • Add "theme" value
  • add a post server method !!!
  • add a put, for edit...

THANK'S EVERYONE
It's finally done ! See you soon

WHat's NEXT ?

a lot of work

  • redux & store
  • unit testing & marble testing
  • explore reactive forms possibilities
  • e2e testing
  • mobile & other target

NG2019 - Découverte FIJ

By Loïc TRUCHOT

NG2019 - Découverte FIJ

  • 296