Architecture MEAN avec Angular 2
Architecture MEAN avec Angular 2
Pierre Pompidor
2 [Link] : 5
2.1 Installation de [Link] : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 ”Hello word” avec Node : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3 Module Express : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3.1 Installation du module Express : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3.2 ”Hello word” avec Node et Express : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3.3 Test du serveur Node avec Express : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.4 Module fs : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.4.1 Création d’un fichier de données JSON ([Link]) : . . . . . . . . . . . . . . . . . . . . . 6
2.4.2 Renvoi au client d’un fichier contenant des données formatées en JSON : . . . . . . . . . . . . 7
2.4.3 Tests du serveur Node avec Express et fs : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.4.4 Renvoi au client de données issues d’un fichier contenant des données formatées en JSON : . 7
3 Aperçu de MongoDB 8
3.1 Installation de MongoDB : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.2 Lancement du service et vérfication de celui-ci : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.3 Utilisation de MongoDB en ligne de commandes : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.3.1 Liste des bases de données : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.3.2 Création d’une base : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.3.3 Création d’une collection : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.3.4 Interrogation d’une collection : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.3.5 Suppression d’un document : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.3.6 Suppression d’une collection : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.4 Installation du module MongoDB pour Node : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.5 Script Node de vérification de la connexion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.6 Exemple d’un script Node/Mongo d’insertion de données : . . . . . . . . . . . . . . . . . . . . . . . . 9
3.7 Exemple d’un script Node/Mongo d’interrogation de données : . . . . . . . . . . . . . . . . . . . . . 10
1
4 ES6 (Javascript 2015) : 11
4.1 Le spécificateur let : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4.2 La fat arrow : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4.3 Les observables : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
5 Angular 2 12
5.1 Introduction : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5.2 Installation : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5.3 TypeScript : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
5.3.1 Typage statique des variables : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
5.3.2 Gestion des classes : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
5.3.3 Gestion d’interfaces : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
5.4 Angular 2 est un framework MVC (voire MVVM) : . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
5.5 Architecture d’une application Angular 2 : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
5.6 La notion de composant : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
5.6.1 Le cycle de vie d’un composant : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
5.7 Le ”Hello world” d’Angular 2 : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
5.7.1 Démarche à suivre : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
5.7.2 Création du composant (Hello/app/[Link]) : . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
5.7.3 L’activation du composant (Hello/app/[Link]) : . . . . . . . . . . . . . . . . . . . . . . . . . 18
5.7.4 Le template HTML (Hello/templates/[Link]) : . . . . . . . . . . . . . . . . . . . . . . . . 18
5.7.5 Le style (Hello/styles/[Link]) : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
5.7.6 Le frontal (Hello/[Link]) : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
5.8 Le ”Hello world” un peu plus avancé : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
5.8.1 Création du composant (Hello/app/[Link]) : . . . . . . . . . . . . . . . . . . . . 19
5.8.2 Création du module (Hello/app/[Link]) : . . . . . . . . . . . . . . . . . . . . . . . . . 20
5.8.3 Le template HTML (Hello/templates/[Link]) : . . . . . . . . . . . . . . . . . . . . . . . . 20
5.8.4 Le style (Hello/styles/[Link]) : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
5.8.5 Le frontal (Hello/[Link]) : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
9 L’injection de dépendances : 26
9.1 Exemple d’injection de service : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2
10 Gestion des routes (le ”routing”) : 27
10.1 Du template vers le contrôleur et du contrôleur vers le composant cible : . . . . . . . . . . . . . . . . 27
10.1.1 Du template vers le contrôleur : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
10.1.2 Du template vers le contrôleur avec une route avec un paramètre : . . . . . . . . . . . . . . . 27
10.2 Du contrôleur vers le composant cible : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
10.2.1 Du contrôleur vers le composant cible sans paramètre : . . . . . . . . . . . . . . . . . . . . . . 27
10.2.2 Du contrôleur vers le composant cible avec un paramètre : . . . . . . . . . . . . . . . . . . . . 27
10.3 Un premier exemple de menu pour invoquer un composant parmi plusieurs : . . . . . . . . . . . . . . 27
10.3.1 Premier composant routable (ExempleRoutes/app/[Link]) : . . . . . . . 28
10.3.2 Second composant routable (ExempleRoutes/app/[Link]) : . . . . . . . . 28
10.3.3 Le menu (Routes/app/[Link]) : . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
10.3.4 Le composant implémentant les routes (Routes/app/[Link]) : . . . . . . . . . . . . . 29
10.3.5 Le module regroupant les composants précédents (Routes/app/[Link]) : . . . . . . . . 29
10.3.6 Le code activant le module (Routes/app/[Link]) : . . . . . . . . . . . . . . . . . . . . . . . . 29
10.3.7 La page web frontale (Routes/[Link]) : . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
10.4 Un exemple plus complet (avec injection et paramétrage d’une route) : . . . . . . . . . . . . . . . . . 31
10.4.1 Le composant RechercheParMarque (ECOMMERCE/app/[Link]) : 32
10.4.2 Le service Recherche (ECOMMERCE/app/[Link]) : . . . . . . . . . . . . . . . 32
10.4.3 Le menu (ECOMMERCE/app/[Link]) : . . . . . . . . . . . . . . . . . . . . . . 33
10.4.4 Le composant implémentant les routes (ECOMMERCE/app/[Link]) : . . . . . . . . . 33
10.4.5 Le module regroupant les composants précédents (ECOMMERCE/app/[Link]) : . . . 34
3
1 Introduction générale :
1.1 Architecture MEAN d’une application web :
Le graphique ci-dessous présente l’architecture d’une application web construite :
— sur le côté serveur avec [Link] qui va :
— répondre à des routes REST
— faire appel à une base de données gérée par MongoDB pour accéder à des documents gérées dans des
collections
— opérer des traitements de filtres avant de renvoyer les données sous formes d’objets javascript sérialisés
(du JSON)
— sur le côté client avec Angular 2 qui :
— gère un seul module (il y aura plusieurs modules dans le projet à développer (voir ci-après))
— gère un composant service injecté dans différents composants
— gère un composant qui fait office de contrôleur.
Les notions de modules, composants et d’injection de services (cas spécifique de l’injection de dépendances)
sont les points les plus intéressants d’Angular 2.
1.2 Le projet :
Le projet consistera à créer une maquette d’une application d’e-commerce respectant les fonctionnalités suivantes :
— cette maquette sera construite via l’architecture MEAN ;
— la base de données MongoDB comprendra au moins deux collections :
— une collection mémorisant les produits en ventes ;
— une collection mémorisant les paniers des clients en cours.
— Angular 2 gérera deux modules :
— un module permettant de rechercher des produits par :
— la liste des types
— la liste des marques
— un type, une marque spécifique...
des raffinements supplémentaires suite à une première recherche (par exemple sur les prix) devront être
aussi possibles.
— un module permettant d’ajouter ou d’enlever des produits dans le panier.
Ces modules pourront donc être ainsi réutilisés dans d’autres applications.
4
2 [Link] :
[Link] est un environnement permettant d’exécuter du code Javascript hors d’un navigateur. Son architecture
est événementielle et modulaire. Il est orienté réseaux car il possède pour les principaux systèmes d’exploitation (Mac
OS, Unix et Windows) des modules réseaux (DNS, HTTP, TCP, TLS/SSL, UDP). Il est réputé pour sa légèreté (vu
sa modularité) et son efficacité.
(Dans ce qui suit, nous dzsignerons [Link] par Node.)
Les composants Angular 2 de notre application client se fourniront donc en données auprès de
services web gérés par Node.
Nous utiliserons deux modules de Node :
— express pour accéder à Node via des URL au format REST ;
— fs pour accéder à des fichiers (par exemple au format JSON) stockés sur le serveur.
Nous utiliserons aussi une connexion à une base de données NoSQL avec MongoDB.
[Link](8888);
5
2.3.1 Installation du module Express :
sudo npm install express
export NODE_PATH=/usr/local/lib/node_modules (dans le .bashrc)
[Link](8888);
2.4 Module fs :
Ce module permet au serveur node d’accéder au système de fichiers et de permettre par exemple à Node de
renvoyer un fichier JSON. sudo npm install -g express
6
2.4.2 Renvoi au client d’un fichier contenant des données formatées en JSON :
Voici un exemple de serveur Node renvoyant au client un fichier contenant des données formatées en JSON.
Ce fichier s’appelle [Link] et le serveur le renvoie sur la route /produits.
var express = require(’express’);
var fs = require("fs");
var app = express();
[Link](8888);
2.4.4 Renvoi au client de données issues d’un fichier contenant des données formatées en JSON :
Cet exemple reprend l’exemple précédent mais la route est ici accompagnée d’un paramètre marque et le serveur
parse la collection Produits désérialisée à partir du fichier [Link] pour ne renvoyer que les données correspon-
dant au paramètre.
7
3 Aperçu de MongoDB
MongoDB est une base de données NoSQL qui gère des données JSON (dans un format optimisé (BSON) :
c’est donc une option idéale pour créer une application web javascriptienne !
Voici le lien officiel : [Link]
8
3.3.5 Suppression d’un document :
[Link](ObjetDeSelection)
9
3.7 Exemple d’un script Node/Mongo d’interrogation de données :
L’interrogation se fait via les correspondances propriété → valeur
La première requête liste tous les documents de la collection Produits,
La seconde requête filtre les documents sur une valeur de propriété.
Les résultats sont affichés dans le terminal.
var MongoClient = require(’mongodb’).MongoClient;
var assert = require(’assert’);
var ObjectId = require(’mongodb’).ObjectID;
var url = ’mongodb://localhost:27017/VentesEnligne’;
10
4 ES6 (Javascript 2015) :
ECMASCRIPT est un ensemble de normes de programmation.
La version 6 (dite abusivement ”Javascript 2015”) a apporté son lot de nouvelles syntaxes : trois mises en oeuvre
par Node vont nous intéresser particulièrement :
Le spécificateur let, les fat arrows et les observables.
Par exemple Angular 2 peut mettre en oeuvre le service http dont la méthode getJson renvoie un obser-
[Link](URL).subscribe(res => [Link] = res,
err => [Link](err),
vable : () => [Link](’done’));
11
5 Angular 2
5.1 Introduction :
Le framework d’application web Javascript Angular 2 créé par Google permet :
— à l’instar d’AngularJS (la première version d’Angular), de découpler les interfaces (la vue du patron de
conception MVC) des traitements métiers et des données (les données et les traitements constituant le modèle
du patron de conception MVC) ;
— d’utiliser des surcouches au langage Javascript pour faire de la programmation objets en utilisant des classes
et le typage statique (dans ce support sera introduite la surcouche TypeScript mais Angular 2 accepte
aussi la surcouche Dart créée par Google) ;
— de créer de vrais composants métiers ainsi que des modules regroupant des composants ;
— en mode développement, de regénérer les pages web dès qu’une modification est effectuée sur les codes sources
(grâce à des scrutateurs = les watchers).
Attention : Angular 2 est vraiment différent de la première version d’Angular.
Angular 2 vise à produire du logiciel réutilisable via la création de composants regroupés en modules.
5.2 Installation :
Pouvant être naturellement couplé avec le serveur Javascript [Link] (voir la seconde section de ce support
de cours), Angular 2 s’installe via le gestionnaire de paquets de NodeJS appelé npm.
Voici la démarche à suivre sous Linux/Ubuntu :
Préliminaire :
sudo apt-get install nodejs npm
nodejs et npm sont déjà installés sur les machines de TP (enfin, je l’espère)
Ensuite vu la multitude de paquets à installer et la complexité des dépendances, je vous conseille de cloner un
projet de base déjà réalisé, par exemple le quickstart TypeScript :
https ://[Link]/docs/ts/latest/[Link].
→ attention : ce polycopié datant du 1er septembre 2016, il se peut donc que les codes que vous allez télécharger et
leurs dépendances soient un peu différents, mais vous devriez pouvoir les adapter sans souci.
Pour le cloner, créez un dossier (par exemple angular2-ts-quickstart) et utilisez git :
mkdir <nomProjet>
git clone https ://[Link]/angular/[Link] <nomProjet>
Votre projet peut simplement s’appeler quickstart.
Déplacez-vous dans le dossier correspondant au projet (angular2-ts-quickstart d’origine mais vous l’avez sans
doute renommé) : cd <nomProjet>
Puis lancez l’installation des paquets décrits dans le fichier de configuration [Link] (ce fichier va décrire
toutes les dépendances nécessaires à l’instar des fichiers manifest sous Java) :
npm install
npm postinstall
Attention :
— cela peut être long... ;
— de vilaines erreurs peuvent apparaı̂tre en rouge sang ;
— mais ce qui est important est la création d’un dossier node modules contenant les modules nécessaires à
l’exécution de votre application
Les paquets npm seront donc installés localement dans le répertoire courant. Si vous êtes administrateur sur
votre machine, vous pouvez aussi les installer globalement (option -g de npm).
Avant de continuer, nous allons découvrir la surcouche au langage Javascript qu’est TypeScript.
12
5.3 TypeScript :
TypeScript est une surcouche au langage Javascript créée par Microsoft en 2012.
Il permet de :
— typer les variables lors de leurs déclarations (typage statique) ;
— créer des classes et les instancier ;
— gérer des interfaces (au sens de la programmation objets) ;
— gérer des spécificateurs d’accès (public, protected, private) ;
— gérer des paramètres optionnels (en ajoutant un point d’interrogation accolé à leurs noms).
Le code Typescript va être transformé en code Javascript via un transpiler (pour ma part j’aime bien utiliser le
terme transcodeur) nommé tsc :
par exemple, en ligne de commande :
tsc [Link]
où [Link] est un code TypeScript → va générer [Link] qui sera un code javascript ”pur”.
Remarquez ainsi que vous pouvez donc mélanger du code Typescript avec du code Javascript et que cela peut
conduire à des sommets fascinants d’illisibilité.
Bien entendu, la valeur de retour d’une fonction peut être aussi typée :
function Bonjour(prenom: string) :string {
return "Bonjour "+prenom;
}
Le contenu de listes ou d’autres variables non scalaires peut être aussi typé :
liste :number[] = [1, 2, 3];
ou
liste :Array<number> = [1, 2, 3];
13
5.3.2 Gestion des classes :
Les classes sont gérées ainsi bien sûr que leur héritage :
class Vehicule {
private avis: string;
constructor(avis: string) {
[Link] = avis;
}
donnerAvis(): void {
[Link]("Avis : "+[Link]);
}
}
14
5.3.3 Gestion d’interfaces :
Les interfaces vont définir le ”comportement” des objets instanciés par la classe.
interface monInterface {
// liste des attributs à définir et des méthodes à implémenter
}
15
5.5 Architecture d’une application Angular 2 :
Voici le contenu type du dossier hébergeant une application Angular 2 utilisant TypeScript (d’autres fichiers
annexes ne figurent pas dans cet exemple) :
dossier de l’application
|
|___ node_modules : les paquets npm installés localement
|
|___ [Link] : le fichier de configuration du projet
|
|___ [Link] : la page web frontale
|
|___ app :le dossier qui va contenir les composants métiers
|
|___ app.<nomComposant>.ts : les composants Angular 2 écrits en TypeScript
|___ app.<nomComposant>.ts
|___ ...
|
|___ app.<nomComposant>.js : les composants Angular 2 transcodés en Javascript
|___ app.<nomComposant>.js (création automatique)
|___ ...
|
|___ [Link] : le code TypScript qui va "activer" les composants
|
|___ templates :
|
|___ <nomComposant>.html : les templates HTML associés aux composants
|___ <nomComposant>.html
|___ ...
|
|___ styles : dossier contant les fichiers CSS (par défaut un fichier [Link] est créé dans l
Maintenant nous allons reprendre notre route en déclinant le quickstart en plusieurs versions.
16
Le template (qui peut être externalisé) définit le code HTML qui va être injecté entre les balises précédemment
définies :
@Component({ selector: ’my-component’})
@View({template: "Hello {{qui}} !"})
class MyComponent {
qui:string = ’toi’;
}
Ce template est défini dans cet exemple dans un objet géré par le décorateur @View Il est aussi possible de
référencer ce template sans utiliser ce décorateur (voir exemple ci-après).
A chaque changement de valeur d’une de ses propriétés, des traitements peuvent être spécifiés dans la méthode
ngDoCheck :
ngDoCheck() { ... }
17
— le fichier d’activation des composants ([Link]) et le frontal ([Link])
— et dans le cas où un fichier TypeScript a été modifié, d’appeler le transcodeur tsc pour générer les fichiers
Javascript correspondants.
Dans ce premier exemple, le nom du composant (Hello) et du fichier qui contient la classe TypeScript qui le
définit ([Link]) ne suivent pas les conventions usuelles :
— le composant devrait se nommer HelloComponent ;
— le fichier devrait se nommer [Link].
C’est juste pour être temporairement rebelle.
@Component({
selector: ’hello’,
templateUrl: ’templates/[Link]’,
styleUrls: [’styles/[Link]’]
})
export class Hello { }
ou avec un décorateur @View (mais qui est déprécié)
import {Component} from ’@angular/core’;
@Component({selector: ’hello’})
@View({
templateUrl: ’templates/[Link]’,
styleUrls: [’styles/[Link]’]
})
export class Hello { }
bootstrap(Hello);
18
<html>
<head>
<title> Hello Word </title>
<meta charset="UTF-8">
... les liens nécessaires les fichiers Javascript
</head>
<body>
<hello> Loading... </hello>
</body>
</html>
Et donc, remontez dans Hello et lancez la commande npm start qui va :
— exécuter la commande associée à l’entrée start dans [Link] :
soit lancer en parallèle le watcher et le transpiler
— le watcher va scruter tous les fichiers qui ont été dernièrement modifiés ;
— et si le fichier modifié est un code typescript (.ts), va appeler le transpiler pour générer le code javascript
associé (.js)
— et votre navigateur devrait vous dire ”bonjour”...
@Component({
selector: ’hello’,
templateUrl: ’templates/[Link]’,
styleUrls: [’styles/[Link]’]
})
export class HelloComponent {
toi :string = ’chef’;
}
19
5.8.2 Création du module (Hello/app/[Link]) :
Vous remarquerez l’import obligatoire du module FormsModule pour mettre en place le two way data bindings.
import { NgModule } from ’@angular/core’;
import { BrowserModule } from ’@angular/platform-browser’;
import { FormsModule } from ’@angular/forms’;
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ HelloComponent ],
bootstrap: [ HelloComponent ]
})
export class AppModule { }
Ces deux aspects seront développés dans la dernière section de ce polycopié sur les compléments à Angular 2.
<span> Bonjour {{toi}} </span> <br/>
<input [(ngModel)]="toi" />
<body>
<hello> Loading... </hello>
</body>
</html>
20
6 Connexion Angular 2 avec Node :
Nous allons maintenant essayer d’opérer une requête Ajax (méthode GET) sur le serveur Node via un
composant nommé Ajax.
Comme pour nos premiers essais Hello, nous allons cloner le quickstart et supprimer le contenu du dossier app.
Notre serveur renverra une collection JSON (la liste des produits sur la route /produits.
@Component({
selector: ’ajax’,
providers: [HTTP_PROVIDERS],
templateUrl: ’templates/[Link]’,
styleUrls: [’styles/[Link]’]
})
export class AjaxComponent {
private http: Http;
public items;
private appel_serveur() {
[Link](’Importation de données’);
[Link](’[Link]
.map((res:Response) => [Link]())
.subscribe(res => [Link] = res,
err => [Link](err),
() => [Link](’done’) );
}
public action() {
this.appel_serveur();
}
}
21
6.1.2 Seconde version :
Cette seconde version (fragments) utilise un objet de type Promise (une promesse à venir...).
Cet objet évite l’empilement de callbacks en proposant un chaı̂nage de la méthode then (d’une manière générale,
pas ici).
...
import ’rxjs/add/operator/toPromise’;
...
[Link](’[Link]
.toPromise()
.then(response => [Link]().data as [Link])
.catch([Link]);
}
bootstrap(AjaxComponent);
6.4 Ajax/styles/[Link] :
button { font-size: 18pt; color: red; }
li { font-size: 18pt; color: green; }
22
6.5 Ajax/[Link] :
<html>
<head>
<title> Importation de données JSON via Ajax </title>
<meta charset="UTF-8">
... les liens nécessaires les fichiers Javascript
</head>
<body>
<ajax> Loading... </ajax>
</body>
</html>
@Component({
selector: ’miroir’,
template: ‘
<input #saisie (keyup)="onKey([Link])">
<p>Valeur : {{value}}</p>
‘
})
export class Miroir {
value:string = ’’;
onKey(value: string) {
[Link] = value;
}
}
23
import {Component, Input} from ’@angular/core’;
@Component({
selector: ’gestionImage’,
template: ‘
<input #saisie (keyup)="changeImage([Link])">
<img [src]="URLImage" />
‘
})
export class GestionImage {
@Input() src:any;
URLImage: string = "[Link]"; // placé ici au-dessus de app
changeImage(URL: string) {
[Link] = URL;
}
}
Dans ce code, nous voyons apparaı̂tre :
— la variable locale qui permet de référencer le noeud de l’arbre DOM correspondant à la balise ;
— le décorateur @Input qui permet de déclarer les attributs de balises HTML pris en charge par Angular.
@Component({
selector: ’dataBinding’,
template: ‘
<input [(ngModel)]="valeur"/>
{{valeur}}
‘
})
export class DataBinding {}
24
8 Les décorateurs usuels :
Un décorateur est le nom d’une structure de patron de conception.
25
9 L’injection de dépendances :
L’injection de dépendances est un point fort d’Angular 2.
Il permet de donner à un composant les dépendances/services dont il a besoin lors de son instanciation.
Dans l’exemple précédent sur le composant Ajax ([Link]) qui sollicitait Node pour récupérer des
données, le module HTTP est directement injecté dans son constructeur.
Ainsi, sous Angular 2, il est donc possible de donner à n’importe quel composant les services dont il a besoin en les
déclarant dans son constructeur :
...
export class ComposantComponent {
...
public constructor(private service :Service, ...) {}
...
}
Le composant ainsi créé être injecté dans d’autres composants qui en auront besoin :
...
export class ComposantComponent {
public items :any;
ngOnInit() {
[Link](params => {
[Link](params[...])
.subscribe(res => [Link] = res,
err => [Link](err),
() => [Link](’done’));
});
}
}
26
10 Gestion des routes (le ”routing”) :
Pour gérer les routes, il faut implémenter un composant spécifique.
Même si la notion de contrôleur perd un peu de son intensité par rapport à la première version d’Angular (AngularJS),
le composant qui va implémenter les routes peut être considéré comme le contrôleur de l’application.
Le routage/routing via des routes REST va être codé en deux étapes :
— du template vers le contrôleur ;
— du contrôleur vers le composant cible.
L’internaute vient de cliquer sur l’item ”Composant2”, le composant2 est invoqué est affiche ”composant2”.
Dans l’exemple suivant, nous aurons les codes suivants :
— les composants :
27
— les deux composants routables :
— Un composant qui affiche ”composant1” (Routes/app/[Link])
— Un composant qui affiche ”composant2” (Routes/app/[Link])
— Le composant qui permet d’appeler l’un des deux composants précédents (Routes/app/[Link])
— Le composant implémentant les routes (Routes/app/[Link])
— le code regroupant les composants dans un module (Routes/app/[Link])
— le code activant le module (Routes/app/[Link])
— la page web frontale (Routes/[Link] ) :)
@Component({
selector: ’composant1’,
templateUrl: ’templates/[Link]’,
styleUrls: [’styles/[Link]’]
})
export class Composant1Component {}
@Component({
selector: ’menu’,
templateUrl: ’templates/[Link]’,
styleUrls: [’styles/[Link]’]
})
export class MenuComponent {
titre = ’Essai sur les routes’;
}
Ce code est lié au template (Routes/templates/[Link] ) :
<span> {{titre}} </span> <br/>
<nav>
<a routerLink="composant1"> Composant 1 </a> <br/>
<a routerLink="composant2"> Composant 2 </a>
</nav>
<br/>
<router-outlet></router-outlet>
Il faut remarquer deux choses importantes :
— routerLink qui définit la route (coir paragraphe ci-après)
— ¡router-outlet¿ qui définit la zone où le composant routé sera interfacé.
28
et au style (Routes/styles/[Link]) :
* { font-size: 24; font-style: bold; }
@NgModule({
imports: [ BrowserModule, FormsModule, routing ],
declarations: [ MenuComponent, Composant1Component, Composant2Component ],
providers: [ appRoutingProviders ],
bootstrap: [ MenuComponent ]
})
export class AppModule { }
29
10.3.7 La page web frontale (Routes/[Link]) :
<html>
<head>
<base href="/">
<body>
<menu> Loading... </menu>
</body>
</html>
30
10.4 Un exemple plus complet (avec injection et paramétrage d’une route) :
Ce second exemple montre :
L’internaute vient de saisir ”Apple” dans la zone de saisie et cliquer sur le bouton ”Recherche par marque”.
Dans l’exemple suivant, nous aurons les codes suivants :
— Les composants :
— Les composants routables (seul le troisième appelé avec un paramètre sera exhibé) :
— Un composant qui affiche les types de produits (ECOMMERCE/app/[Link])
— Un composant qui affiche les marques des produits (ECOMMERCE/app/[Link])
— Un composant qui affiche les produits d’une marque donnée (ECOMMERCE/app/RechercheParMarq
— Le composant qui implémente le service HTTP utilisé par les trois composants précédents
(ECOMMERCE/app/[Link])
— Le composant qui permet d’appeler l’un des composants (ECOMMERCE/app/[Link])
— Le composant implémentant les routes (ECOMMERCE/app/[Link])
— Le code regroupant les composants dans un module (ECOMMERCE/app/[Link])
— Le code activant le module (ECOMMERCE/app/[Link]) → même structure que dans le premier exemple
— La page web frontale (ECOMMERCE/[Link] ) :) → même structure que dans le premier exemple
31
10.4.1 Le composant RechercheParMarque (ECOMMERCE/app/[Link]) :
import {Component, OnInit} from ’@angular/core’;
import {ActivatedRoute} from ’@angular/router’;
import { RechercheService } from ’./[Link]’;
@Component({
templateUrl: ’templates/[Link]’,
})
export class RechercheParMarqueComponent {
public items :any;
ngOnInit() {
[Link](params => {
[Link]("marque/"+params[’marque’])
.subscribe(res => [Link] = res,
err => [Link](err),
() => [Link](’done’));
});
}
}
@Injectable()
export class RechercheService {
constructor(private http :Http) {}
return observable;
}
}
32
10.4.3 Le menu (ECOMMERCE/app/[Link]) :
import {Component} from ’@angular/core’;
@Component({
selector: ’menu’,
templateUrl: ’templates/[Link]’,
styleUrls: [’styles/[Link]’]
})
export class MenuComponent {
titre = ’Recherche sur les produits’;
marque :string = ’Apple’;
33
10.4.5 Le module regroupant les composants précédents (ECOMMERCE/app/[Link]) :
import { NgModule } from ’@angular/core’;
import { BrowserModule } from ’@angular/platform-browser’;
import { HttpModule } from ’@angular/http’;
@NgModule({
imports: [ BrowserModule, HttpModule, routing ],
declarations: [ MenuComponent, RechercheMarquesComponent, RechercheTypesComponent, RechercheParM
providers: [ RechercheService ],
bootstrap: [ MenuComponent ]
})
export class AppModule { }
34
Index
écouteurs d’événements, 23 npm, 5, 12
npm install, 12
Angular 2, 12 npm start, 17, 19
AngularJS, 12
any, 13 Observable, 21
Architecture MEAN, 4
[Link], 12
BSON, 8 Promise, 22
Property binding, 23
classe injectable, 26
Composant, 16 quickstart TypeScript, 12
CRUD, 5
require, 5
Décorateur, 16, 25 routerLink, 27
Décorateur Component, 16, 25 routes, 27
Décorateur Injectable, 25, 26 Routes router-outlet, 28
Décorateur Input, 24, 25 Routes routerLink, 28
Décorateur NgModule, 25 routing, 27
Décorateur View, 17
Dart, 12 sélecteur, 16
doubles accolades, 23 spécificateur let, 11
subscribe, 11
ECMASCRIPT, 11
ES6, 11 transpiler, 13, 19
Event Binding, 23 tsc, 13, 18
Express, 5 two way data binding, 15, 20, 24
TypeScript, 13
Fat arrow, 11 TypeScript classe, 14
TypeScript interface, 15
Injection de dépendances, 26 TypeScript typage statique, 13
injection de service, 21
variable locale, 24
Les observables, 11
lite-server, 17 watcher, 12, 19
map, 21
Modèle MVC, 15
Modèle Vue-Vue-Modèle, 15
MongoDB drop, 9
MongoDB find, 8
MongoDB insert, 8
MongoDB mongoimport, 8
MongoDB remove, 9
MongoDB show dbs, 8
MongoDB use, 8
MVC, 15
MVVM, 15
ngDoCheck, 17
ngOnInit, 17
Node, 5
node modules, 12, 16
[Link], 5, 12
NoSQL, 8
35