jeudi 2 août 2018

Note d'intégration d'angular et Spring 5

Tout développeur web a déjà eu l’occasion de développer un formulaire, que ce soit pour une page de login, un formulaire de contact ou un CRUD (Create, Read, Update, Delete) d’une entité d’un backend.

Pour pouvoir faire le TP suivant vous pouvez utiliser le site suivant :

https://stackblitz.com/edit/angular-pvarts?file=src%2Fapp%2Fapp.component.ts

Qu'est ce que Angular?

-- Développer par Google
-- Oreintée composant 
-- Multi platfrom
-- Support multi langage
-- Framework reactive
-- Injection des dependences
-- Shadow DOM 
-- Composant Web Friendly

Les principaux Blocs d'Angular :

-- Modules
-- Composants
-- Templates
-- Metadata
-- Data binding
-- Directives
-- Services
-- Injection des dependences
overview

Qu'est ce que TypeScript?


--Sur ensemble de JavaScript typée
--Se compile en JavaScript
--Open source
--Syntaxe similaire à Java

Transpiler :
Compile le TypeScript en JavaScript (ES5)

On peut modifier la version de JavaScript dans le fichier :" tsconfig.json", puis la propriété 'target'

TypeScript tips :


La déclaration du constructeur avec des paramètres 'public' ou 'private'

est un raccourcis pour créer est initialiser les les membres de la classe en une seul fois.

Notions de build :

Build-time transpilation : Angular CLI

Runtime transpilation : Au moment de l’exécution du navigateur.

  1. Mise en place de l'environnement de dév.
--Installer NodeJS =>node -V v7 & npm 3

Création de l'application avec Angular CLI.

-- scaffolder de la part de gOOGLE :  exposant un ensemble de commandes permettant d’accélérer le processus d’initialisation du projet.
-- facilite la création des applications Angualr

-- npm install -g @angular/cli
-- npm update @angular/cli en cas de probléme 
-- ng new "le nom du projet"
-- cd "nom du projet"
-- ng serve 

Création de composants Angular :

-- Metadata / Decorator : (@Component @Input/ @Output / @NgModule / @ Injectable)permettent de décrire à Framework Angualr comment interpréter un élément, Le gros avantage des décorateur est de bien séparer la partie métiers des informations techniques..
-- Modules
-- Directives
-- Composants
-- Templates et styles

Les paramétrés de @NgModule:

Permet d’organiser une application en modules fonctionnels ou techniques 
--declarations : définit tous les éléments embarqués dans le module (composants, directives, pipes, etc.).
--Exports : Les composants que nous voulons rendre disponible aux autres
--Imports : Permet d'importer les modules dont nous avons besoin au niveau du module courant.
--Providers : Liste les services utilisés par le composant
--Bootstrap : définit une réference vers la vue principale (Composant racine de l'application)

Création d'un module avec la CLI Angular: ng g module login

 Après la création il faut ouvrir le module :
 import {LoginModule} from './login/login.module';
 app.module.ts et dans @NgModule -> imports ajouter LoginModule

 Comment Débogger?

 S'il y a une erreur on la trouvera dans la console.

Comment faire un affichage?


 Notre module est créer, maintenant nous allons voir comment faire un affichage.
 A l'aide des composants (components) qui sont l'un des trois directivces d'Angular.

  •  Un composant correspond à une classe exposant une vue et définissant la manière dont l’utilisateur interagit avec cette vue
  •  Une directive est un élément du framework qui va interagir directement avec le DOM de notre page HTML
 --Components directives : possèdent la spécificité d’être associer à un Template

 --Structural directives : Ces directives, en opposition aux directives d’attribut, modifient directement l’arborescence du DOM HTML.
Elles peuvent donc ajouter, modifier ou supprimer des éléments au cours de l’exécution de l’application.

 --Attribute directives : ne modifient pas l’arborescence du DOM, elles ne vont ni créer ni supprimer des éléments HTML, mais vont agir sur les attributs et les propriétés des balises HTML existantes.. Elles sont notamment utilisées pour modifier l’apparence (en modifiant le style) ou le comportement (en modifiant les handlers) d’un élément existant.

Création d'un composant : 

 cd src/app/login/
 ng g component authentification
 Dans le module LoginModule on voit que declarations: [AuthentificationComponent] a été ajouté.
 Pour la rendre exploitable par les autres modules on doit l'ajouter au paramétrés "Exports":, dans login.module.ts
 Donc : exports: [AuthentificationComponent] dans @NgModule 
 Maintenant nous allons personnaliser le css et html de notre component.
 --authentification.component.css => p{ color : green}
 --authentification.component.html => Login component
 Pour savoir le component tag de votre application il faut ouvrir :
 --authentification.component.ts
 puis, dans @Component le paramétre selector : dans notre cas, c'est :
 app-authentification
 copier, coller dans app.component.html
 --Relancer "ng serve"


 Création d'un service Angular.

 -- Comment utiliser?
--Services.
--Injection des dépendances.

Injection des dépendances:

Le principe de ce pattern est de casser les dépendances entre les éléments.
Donc avoir une couplage faible entre les élements et ainsi permettre une meiulleur maintenance. et facilite l'ecriture des tests.

Dans le cadre d’Angular, un composant peut avoir besoin d’un service, on dit alors que le composant est dépendant du service. Le framework Angular joue alors le rôle de gestionnaire de dépendances.
Angular implemente une fonctionnalité qui permet d'utiliser ce mecanisme.

-- Le Framework Angular récupere les informations du service dont-il a besoin à partir de la proprietes "provider" du décorateur @NgModule, qui est le niveau le plus haut de l'application.
Lorsqu’un service est déclarée à ce niveau de l’application est généralement un singleton, à chaque fois qu’un élément du Framework demande ce service, ce sera la même instance qui lui sera retournée. Les dépendances déclarées à ce niveau agissent donc comme des singletons.

-- Si nous voulons crées des instances unique à chaque composants, il faut utiliser la propriété "provider" du décorateur @Component

Services Angular:

Dans l'architecture Angular L’objectif d’un service est de contenir toute la logique métier de l’application.
-- Le service doit avoir une seul responsabilité.
-- On peut injecter un service à l'aide l'annotation @Injectable.
 Ce décorateur n’est donc pas obligatoire lorsque le service ne possède aucune dépendance, mais le mettre dans tous les cas est une bonne pratique que nous vous conseillons.

 Création d'un service : cd src/app/login/


 Angular CLI : ng g service authetification
 crée : authentification.service.spec et authentification.service.ts
 Annotée @Injectable
 Pour utiliser ce service il faut le fournir dans la proprietes "providers" de @NgModule du module LoginModule.

 Donc, il faut import {AuthentificationService} from './authentification.service';
 Puis : providers: [AuthentificationService], dans @NgModule

 Pour pouvoir utiliser le service dans authentification.component, il faut :
 import {AuthentificationService} from '../authentification.service';

 Puis, dans le constructeur : constructor(public authentificationService: AuthentificationService)

 Nous mettons l'accesseur à public pour qu'il soit visible par tout les composants.

 Maintenant, nous allons utiliser le service et lui demander si un utilisateur et login ou non?
 this.authentificationService.isLoggedIn(this.username);

 Maintenant, créons la variable username:
 username = 'Naoufal';
 // Variable qui affiche le message retournée par le service
 isLoggedIn: boolean = false;
  ngOnInit() {
    this.isLoggedIn = this.authentificationService.isLoggedIn(this.username);
  }
  
  Pour afficher la variable isLoggedIn, nous devons modifier le fichier authetification.component.html
  Composant d'authentification !
  {{username}} -- {{isLoggedIn}}
-- Les informations sont afficher corectement.
Pour s'assurer que l'appel au service se fait correctement, nous allons changer le username.

L'interaction avec l'utilisateur au moyen d'un formulaire:

Les champs d'inputs d’un composant:

Data binding dans Angular:

-- Laison des données : Ce "data binding" va permettre de synchroniser les données entre les composants et les vues.

Une modification d’une propriété d’un composant sera automatiquement reflétée sur l’interface, et inversement une modification d’un contrôle HTML mettra à jour les propriétés du composant.
Binding supporter par Angular (DOM <-> Component):
<->
Angular a défini quatre sortes de Data Binding pour synchroniser le template et le Component:
databinding

  1. {{value}}Interpolation => Ce mécanisme permet de modifier le DOM à partir du modèle, si un changement est intervenu sur une valeur de ce dernier.
  2. [propriete] = "valeur" : Ce mécanisme permet de valoriser une propriété d'un composant ou d'une directive à partir du modèle, si un changement est intervenu sur une valeur de ce dernier.
  3. (evenement) = "fonctionHandler" : Ce mécanisme permet d'exécuter une fonction portée par un Component suite à un évènement émis par un élément du DOM.
  4. [(ng-model)] = "propriete"

--Event Binding (Laison d'evenement) : permet à une application Angular d’exécuter du code, des actions, lorsqu’un événement est levé.

il suffit de décorer de parenthèses le nom de l’événement DOM à écouter et de fournir la méthode à exécuter sur cet événement
L'objet $event : Un objet est disponible dans la variable $event fournie par Angular. C’est cet objet qui contient la donnée que nous voulons récupérer. Une première solution est de passer cet objet $event dans une méthode et d’aller chercher l’entrée utilisateur à l’intérieur.


 La vue et le data binding

Le "two-way" Data Binding : 

C'est une combinaison du Property Binding et du Event Binding sous une unique annotation.
Dans ce cas là, le component se charge d'impacter le DOM en cas de changement du modèle, et le DOM avertit le Component d'un changement via l'émission d'un évènement.
Le mécanisme se rapproche du fameux ngModel Angular 1, mais avec des algorithmes de Data Binding différents.  
Pour pouvoir afficher et éditer le nom du produit, la syntaxe ngModel est nécessaire.
Il suffit d’assigner la propriété du produit avec ngModel pour que la liaison de donnée soit effective. Si l’utilisateur édite le champ dans l’input, la variable dans le code sera modifiée, et la réciproque est aussi vraie.
Cela veut dire que si une méthode ou un mécanisme est amené à modifier le nom du produit, l’utilisateur verra cette modification immédiatement dans son interface.

'ngModel' en détail :

Pour comprendre exactement ce qui se passe lorsqu’on utilise l’instruction [(ngModel)], il faut décortiquer la structure de sa syntaxe.

Les deux crochets [ ], représentent le property binding (la liaison à la propriété).
Cela signifie que la valeur circule depuis le modèle (dans le code) vers ce qui est affiché dans la vue.
C’est tout simplement le one-way (unidirectionnel) data binding du modèle vers la vue.

Les deux parenthèses ( ), quant à elles, représentent l’event binding (la liaison à l’événement).
C’est l’inverse du property binding, car c’est la vue qui va notifier le modèle d’un événement.
C’est un one-way data binding de la vue vers le modèle dans ce cas.

Ainsi, en utilisant les deux ensembles, un two-way data binding est créé et le flux circule dans les deux sens.

Pour plus d'information : https://vsavkin.com/two-phases-of-angular-2-applications-fda2517604be

Création d'un champ de saisi avec Angular 

Nous allons changer le fichier authentification.component.html




Nous devons utiliser les varaibles de réference de template pour récupérer les donnes de ces champs et les envoyer au composant.
avec références d’élément : Hash #username et #password

 
 
 
 
 
  
 Nous pouvons référencer ces champs à l'aide des Hash reference.
 Maintenant nous devons envoyer ces donners à nos composants.
 Donc nous allons utiliser un eventHandler au moment du click :
 
"login(username.value, password.value)">Se connecter
 Pour faciliter le déboggage nous allons afficher le user et le password après le button.

 utilisateur : {{username.value}} -- mot de passe : {{password.value}}

 Maintenant nous allons ajouter la méthode login() à notre composant d'authentification: AuthntificationComponent.

Systeme de détection du changement avec Angular:

Une application est basée sur un ensemble de modèles. L’objectif est de présenter ces modèles sous une forme ou une autre en tant qu’interface pour l’utilisateur. 
Dans le cas d’une application Angular, l’interface est le DOM, et donc le modèle est alors converti en un ensemble d’éléments DOM : des blocs, des listes, des éléments HTML 5, etc.

L’affichage de cette interface est relativement simple.
D’une part, il y a une entrée, le modèle de l’application, il peut être sous forme d’objets, de tableaux, de références d’objets.
D’autre part, il y a une sortie, le DOM. Ainsi, si l’on s’en tient à du rendu basique, une simple méthode de rendu suffirait.

--Les sources qui peuvent provoquer des changements, elles sont au nombre de trois :
  1. les événements, 
  2. les XHR et 
  3. les timers
--Chaque composant possède son propre détecteur de changement, et cela est une bonne nouvelle, car il va alors être possible de gérer la détection du changement pour un composant spécifique, si besoin.


--change-detection=onpush


Zones
https://blog.zenika.com/2016/11/15/les-zones/ 

Pour notifier Angular du moment auquel la détection de changement doit être effectuée, ce sont les Zones qui sont utilisées. Pour comprendre le concept des Zones, il est important de comprendre comment la call stack (pile d’exécution) fonctionne en JavaScript. JavaScript étant mono thread, il ne peut faire qu’une seule chose à la fois, ainsi, un code synchrone va remplir la call stack normalement puis la vider tout aussi normalement.

En réalité, Angular utilise sa propre Zone NgZone, qui est une Zone qui met à disposition plusieurs APIs basées sur les observables.

--change-detection=onpush

Afficher la variable 'counter' dans la template.

Les requêtes HTTP:

Angular fournit un module HTTP,  Le module HTTP expose plusieurs méthodes permettant d’envoyer et recevoir des données via des requêtes HTTP.

--HttpModule 

Pour utiliser ce module il faut importer ça dependence @angular/http. (Déjà inclus dans package.json fourni par Angular CLI)
il faut l'implementer par AppModule.
il utilse XHR pour transfert les données du serveur vers le client.
RequestOptions permet d'ajouter des options à l'en-têtes HTTP.

Il supporte tous les verbes REST:
-GEt
-POST
-PUT
-Delete
-PATCH


--Il faut l'importer dans login.module.ts
@NgModule --> imports:[HttpModule]

Puis, dans authentification.service.ts, nous allons implementer notre logique métier.
Sachant que nous n'avons pas de backend encore nous allons créer un fichier:
login.json dans le répertoire assets.

Maintenant, nous allons changer notre service pour qu'il fasse des appels HTTP.
import { Http, Response } from '@angular/http';

Redefinition de la méthode isLoggedIn:

  constructor(public http: Http) { }

  public isLoggedIn(username: string, password: string): Observable {
    // Appel d'un fichier staitique avec la méthode get dans le répertoire 'assets'
    return this.http.get('./assets/login.json')
      // On map la réponse avec la fonction, puis on verifie que le 'username' et le 'password'de la réponse et le même saisie par le 'user'
      .map((res: Response) => {
        return res.json().username === username &&
          res.json().password === password;
      })
      // On vérife qu'on n'a pas d'erreur, et on cas d'erreur, on affiche le code status retournée par l'appel HTTP 
      .catch((error: any) => {
        return Observable.throw(error.statusText)
      });

  }
  

/!\  Faire Attention à Observable :

Il faut ajouter import :
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';


Puis, changer le retour de la méthode isLoggedIn en Observable

Maintenant, nous devons adapter la méthode du AuthentificationComponent, ne retourne plus un boolean, mais un Observable.

Donc nous devons souscrire pour récupérer la réponse.

 login(username: string, password: string) {
     this.authentificationService.isLoggedIn(username, password).subscribe(
       res => this.isLoggedIn = res,
       error => this.connectionError = error
     );
  }
  
-- Nous allons lancer notre application pour s'assurer quelle marche correctement.
--Ouvrir la console pour montrer l'appel XHR request response
--Catcher une exception lors change de ressource 'login_inexistant'

Comment ajouter un en-tête (header) à notre code HTTP de AuthentificationService?


Nous devons créer un Objet Header avec le type X-custom et placer dans RequestOptions.
Puis, placer la RequestOptions dans la méthode get de HTTP.
 let headers = new Headers({'Content-Type': 'X-custom'});
 let option = new RequestOptions({headers: headers});
 /!\ import { Headers, Http, RequestOptions, Response } from '@angular/http';
 Recap:
 --Comment créer une app Angular avec Angular CLI?
 --Comment créer des composant Angular?
 --Comment créer des service Angular?
 --Comment créer des champs de saisie Angular?
 --Comment utiliser les requêtes HTTP?
   

Les directives d'Angular:

 ngForngIfngClassngStyle, et ngSwitch

Les interactions entre components

Faire circuler de l'information d'un parent vers un enfant :

Il est possible de transmettre une donnée d'un parent vers un component enfant à l'aide du mécanisme de Property Binding

Tools :



Angular Language Service : outil d'autocompletion pour les templates html

https://angular.io/guide/language-service


Augury : Extension de Chrome Dev Tools pour débugger des applications Angular : 

https://augury.angular.io/

Unit Testing AngularJS :


Aucun commentaire:

Enregistrer un commentaire

to criticize, to improve