Vous êtes sur la page 1sur 13

Formation JEE Pr. M.

LETHRECH SupMTI

TP1 Angular
Objectifs du TP

IDE utilisé : IntelliJ IDEA


I- Installation de l’environnement de développement
Installation de l’environnement de travail : https://angular.io/guide/setup-local

1- Installer Node.js

If you are unsure what version of Node.js runs on your system, run node -v in a terminal
window.

2- npm package manager (Node Package Manager) : installé automatiquement avec


Node.js
To check that you have the npm client installed, run npm -v in a terminal window

3- Install the Angular CLIlink


The Angular CLI is a command-line interface tool that you use to initialize, develop, scaffold,
and maintain Angular applications directly from a command shell.

Utiliser la commande : npm install -g @angular/cli


Commande : « ng - -version » retourne la version d’Angular installée

Installation des extensions suivantes :

- Angular Language Service : Complétion typescript à l’intérieur du HTML


- Prettier - Code formater : Pour formater le code source (ctrl+shift+p)
- ESLint : Détection des erreurs et proposition de solutions

II- Création du projet

1
Formation JEE Pr. M. LETHRECH SupMTI

Créer un dossier de travail « workspace » et y positionner l’invite de commande


Création du projet Commande : « ng new web-cat-app”
 C:\...\workspace\web-cat-app
En positionnant l’invite de commande à l’intérieure de votre projet « web-cat-app »
taper la commande
 ng serve

Tester l’URL http://localhost:4200/


« Ng serve » permet de compiler le projet (génération du javascript) et lancer le
serveur.
Les interfaces angular sont de type single page Application (SPA).
Séquence d’exécution :
Angular démarre  exécution de main.ts  main.ts va charger le module
app.module  app.module va charger le composant app.component sur index.html
Création d’un nouveau composant :
ng new component nom_composant

III- Configuration de json-server


Sur le terminal de IntelliJ Idea exécuter les commandes :
- npm install --save json-server
- npm install --save concurrently
(Si vous avez fait un check-out du projet il faut installer les dépendances (voir
package.json) en utilisant « npm install »)
Au niveau de la racine du projet créer un fichier json appelé « db.json » :
{
"products": [
{
"id": 1,
"name": computer,
"price": 10000,
"quantity": 120,
"selected": true,
"available": true
},
{
"id": 2,
"name": "printer",
"price": 1000,
"quantity": 30,
"selected": true,
"available": false
},
{
"id": 3,

2
Formation JEE Pr. M. LETHRECH SupMTI

"name": "smartphone",
"price": 3000,
"quantity": 5,
"selected": false,
"available": true
}
]
}
Sur le fichier package.json ajouter les modifications suivantes au niveau des scripts :
"start": "ng serve",
Par
"start": "concurrently \"ng serve\" \"json-server --watch db.json\"",
Ensuite démarrer le serveur via la commande :
Npm start
Tester l’URL : http://localhost:3000/products
http://localhost:3000/products/?id=1
http://localhost:3000/products/?name_like=p

Utilisation de « Advanced rest client » “ARC” de google pour ajouter des éléments :

3
Formation JEE Pr. M. LETHRECH SupMTI

Méthode post pour ajouter des éléments, put pour mettre à jour….

Installation de bootstrap/jquery :
Npm install –save bootstrap
Npm install –save jquery
Npm install –save font-awesome

Création du composant menu :


Ng g c components/nav-bar
Récupérer un navbar de boostrap du site w3cSchools :

4
Formation JEE Pr. M. LETHRECH SupMTI

nav-bar.component.html

<nav class="navbar navbar-expand-sm bg-dark navbar-dark">


<!-- Brand -->
<a class="navbar-brand" href="#">Logo</a>

<!-- Links -->


<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" routerLink="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/products">Products</a>
</li>

<li class="nav-item dropdown">


<a class="nav-link dropdown-toggle" href="#" role="button" data-
bs-toggle="dropdown">Dropdown</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Link</a></li>
<li><a class="dropdown-item" href="#">Another link</a></li>
<li><a class="dropdown-item" href="#">A third link</a></li>
</ul>
</li>
</ul>
</nav>

Intégration de bootstrap et jquery : Au niveau du fichier angular.json


"styles": [
"src/styles.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/bootstrap/dist/js/bootstrap.min.js"
]

Une autre manière d’intégration consiste en l’utilisation du fichier style.css :


@import "~font-awesome/css/font-awesome.min.css";

Au niveau du fichier app.component.html après la suppression du contenu ajouter :


<app-nav-bar></app-nav-bar>

Ajouter deux autres composants :


ng g c components/products

5
Formation JEE Pr. M. LETHRECH SupMTI

ng g c components/home
Ajouter les routes sur le fichier : app-routing.module.ts
const routes: Routes = [
{path:"products", component:ProductsComponent},
{path:"", component:HomeComponent}
];
Sur le fichier nav-bar.component.html modifier les liens :
<li class="nav-item">
<a class="nav-link" routerLink="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/products">Products</a>
</li>

Il faut importer HttpClientModule : sur le fichier app.module.ts ajouter


HttpClientModule
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule
],

Création d’un service de récupération des produits :


Créer un dossier services sur le dossier app
Au niveau du fichier environment.ts créer la variable path :
export const environment = {
production: false,
host:"http://localhost:3000"
};

Créer une classe products.service.ts au niveau du dossier app/services :


import {Injectable} from "@angular/core";
import {HttpClient} from "@angular/common/http";
import {environment} from "../../environments/environment";
import {Observable} from "rxjs";
import {Product} from "../model/product.model";

@Injectable({providedIn:"root"})
export class ProductsService{
constructor(private http:HttpClient) {
}

getAllProducts():Observable<Product[]>{
let host = environment.host;
return this.http.get<Product[]>(host+"/products");
// return this.http.get("http://localhost:3000/products");
}
getSelectedProducts():Observable<Product[]>{
let host = environment.host;
return this.http.get<Product[]>(host+"/products?selected=true");
}

6
Formation JEE Pr. M. LETHRECH SupMTI

getAvailableProducts():Observable<Product[]>{
let host = environment.host;
return this.http.get<Product[]>(host+"/products?available=true");
}
}

Au niveau du composant products : products.component.ts

import { Component, OnInit } from '@angular/core';


import {ProductsService} from "../../services/products.service";
import {Product} from "../../model/product.model";

@Component({
selector: 'app-products',
templateUrl: './products.component.html',
styleUrls: ['./products.component.css']
})
export class ProductsComponent implements OnInit {
products?:Product[];
// products:Product[]|null=null;
constructor(private service:ProductsService) { }

ngOnInit(): void {
}

onGetAllProducts() {
this.service.getAllProducts().subscribe(data=>{
this.products = data;
})
}
}

Sur le dossier app, créer un dossier model ensuite créer la classe Product
(product.model.ts) comme suit :

export interface Product{


id:number;
name:string;
price:number;
quantity:number;
selected:boolean;
available:boolean;
}
products.component.html

<nav class="navbar navbar-expand-sm bg-light navbar-light">


<ul class="navbar navbar-nav">
<li>
<button (click)="onGetAllProducts()" class="btn btn-outline-info
m-lg-2">All</button>

7
Formation JEE Pr. M. LETHRECH SupMTI

</li>
<li>
<button class="btn btn-outline-info m-lg-2">Selected</button>
</li>
<li>
<button class="btn btn-outline-info m-lg-2">Available</button>
</li>
</ul>
</nav>

<div class="container" *ngIf="products">


<table class="table">
<tr>
<th>ID</th>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Selected</th>
<th>Available</th>
</tr>
<tr *ngFor="let p of products">
<td>{{p.id}}</td>
<td>{{p.name}}</td>
<td>{{p.price}}</td>
<td>{{p.quantity}}</td>
<td>{{p.selected}}</td>
<td>{{p.available}}</td>
</tr>

</table>
</div>

Tester votre application sur http://localhost:4200/ (commande pour démarrer le


serveur : npm start)

8
Formation JEE Pr. M. LETHRECH SupMTI

Ajout d’un bouton de recherche :


Ajouter sur la nav Bar :

<ul class="navbar navbar-nav m-lg-auto">


<li>
<form #f="ngForm" (ngSubmit)="onSearch(f.value)"
class="inline">

<input ngModel name="keyword" type="text">


<button class="btn btn-sm btn-outline-info m-lg-2">
<span class="fa fa-search"></span>
</button>

</form>
</li>
</ul>
Au niveau du script product.component.ts ajouter :

onSearch(dataForms : any){
this.products$ =
this.service.searchProducts(dataForms.keyword).pipe(
map(data=>({dataState:DataStateEnum.LOADED,data:data})),
startWith({dataState:DataStateEnum.LOADING}),
catchError(err=>of({dataState:DataStateEnum.ERROR,
errorMessage:err.message}))
);
}
Avec la création de l’objet product.stat.ts :

export enum DataStateEnum {


LOADING,
LOADED,

9
Formation JEE Pr. M. LETHRECH SupMTI

ERROR
}

export interface AppDataState<T> {


dataState?:DataStateEnum,
data?:T,
errorMessage?:string
}

Avec la variable product sur le fichier product.componenet.ts 

products$:Observable<AppDataState<Product[]>> | null = null;

Avec la méthode suivante sur le service products.service.ts :

searchProducts(keyword:string):Observable<Product[]>{
let host = environment.host;
return
this.http.get<Product[]>(host+"/products?name_like="+keyword);
}

Ajout des boutons sur product.componenet.ts :

<td>
<button (click)="onSelect(p)" [ngClass]="p.selected?'btn-
success':'btn-danger'" class="btn btn-sm">
<span *ngIf="p.selected">Unselected</span>
<span *ngIf="!p.selected">Selected</span>
</button>
</td>
<td>
<button (click)="onDelete(p)" class="btn btn-sm btn-danger"
>
<span class="fa-trash-o" ></span>
</button>
</td>

Avec le comportement sur product.component.ts

onSelect(p:Product){
this.service.select(p).subscribe(data=>{
p.selected = data.selected;
})
}

onDelete(p:Product){
let v = confirm("etes vous sure")
if(v==true)
this.service.delete(p).subscribe(data=>{

10
Formation JEE Pr. M. LETHRECH SupMTI

this.onGetAllProducts();
})
}

Avec le comportement suivant sur products.service.ts :

select(product:Product):Observable<Product>{
let host = environment.host;
product.selected = !product.selected;
return
this.http.put<Product>(host+"/products/"+product.id,product);
}

delete(product:Product):Observable<void>{
let host = environment.host;
return this.http.delete<void>(host+"/products/"+product.id);
}

Réactive forms
Création d’un formulaire : ng g c components/product-add
Ajout d’un nouveau bouton : sur products.component.html

<li>
<button (click)="onNewProduct()" class="btn btn-sm btn-outline-
info m-lg-2">New Product</button>
</li>

IntelliSense
Pour ajouter la completion css a visual studio code ajouter l’extension Zignd

11
Formation JEE Pr. M. LETHRECH SupMTI

Déploiement de l’application :
Modifier le fichier index.jsp
La ligne
<base href="/">
Par
<base href="./">

Exécuter la commande : ng build –prod


 un dossier « dist » contenant la compilation du projet sera créé

Copier le dossier dist/web-cat-app sur le dossier wamp\www d’apache et tester


l’URL suivante : http://localhost/web-cat-app/

12
Formation JEE Pr. M. LETHRECH SupMTI

Sources

Pr Mohame Youssfi (ENSET)

Des radars
https://www.thoughtworks.com/radar

https://www.infoq.com/

https://qconlondon.com/

Autres champs à développer

Application statful / statless

Transaction manager

Security

Structuration de la BD

Partie déploiement : docker, …

13

Vous aimerez peut-être aussi