Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

đŸ…°ïž Angular – Framework Complet (Installation, Core & DĂ©ploiement)

Guide complet IDEO‑Lab sur le framework TypeScript (Composants, DI, RxJS, CLI).

1.1

Vue d'ensemble

Framework "batteries incluses", TypeScript, SPA.

Framework TypeScript SPA
1.2

Architecture

Modules (NgModules), Composants, Services, DI.

Composants Modules DI
1.3

Installation (Angular CLI)

npm install -g @angular/cli, Node.js.

@angular/cli npm
1.4

CLI : ng new & ng serve

Créer et servir un projet, Standalone vs Modules.

ng new ng serve Standalone
2.1

Anatomie d'un Composant

@Component, Sélecteur, Template, Style (scopé).

@Component selector
2.2

@NgModule (Ancien)

declarations, imports, providers, bootstrap.

@NgModule imports
2.3

Composants Standalone

standalone: true (moderne), imports: [...].

standalone Angular 17+
2.4

Templates : Data Binding

Interpolation {{}}, Property [], Event (), Two-Way [()].

{{ }} [ ] ( )
2.5

Directives

*ngIf (@if), *ngFor (@for), [ngClass], [ngStyle].

@if / *ngIf @for / *ngFor
2.6

Pipes (|)

date, currency, uppercase, async.

| date | async
3.1

Services

Logique métier, Singleton, @Injectable.

@Injectable Singleton
3.2

Injection de Dépendances (DI)

providedIn: 'root', constructor(private ...).

DI constructor
3.3

Routage (RouterModule)

Routes, <router-outlet>, routerLink.

RouterModule router-outlet
3.4

Routage (Avancé)

ParamĂštres (:id), Guards, Lazy Loading.

ActivatedRoute Guards
4.1

HttpClient

HttpClientModule, http.get(), Observables.

HttpClient subscribe
4.2

RxJS & Observables

Concept de "Stream", subscribe(), | async.

RxJS Observable
4.3

Formulaires (Template-driven)

FormsModule, ngModel, #form="ngForm".

FormsModule ngModel
4.4

Formulaires (Reactive)

ReactiveFormsModule, FormBuilder, FormGroup.

Reactive Forms FormGroup
5.1

Déploiement (`ng build`)

ng build, dist/, Nginx (try_files).

ng build dist/
6.1

Cheat-sheet (CLI & Hooks)

ng g c, ng g s, Lifecycle Hooks.

cheat ng g
1.1 Vue d'ensemble : Le Framework "Batteries Incluses"
Angular est un Framework, React est une BibliothĂšque

C'est la distinction la plus importante.
React (BibliothÚque) : Ne gÚre que la "Vue" (l'UI). Vous devez choisir et assembler d'autres librairies pour le routage, les appels HTTP, la gestion d'état, etc.
Angular (Framework) : Est une solution "batteries incluses" (opinionated). Il fournit une solution officielle pour tout :

  • Composants (UI)
  • Routage (@angular/router)
  • Appels HTTP (@angular/common/http)
  • Gestion de formulaires (@angular/forms)
  • Injection de dĂ©pendances (DI) (natif)

Vous n'avez pas Ă  choisir votre stack, vous suivez "la voie Angular".

Philosophie & Concepts Clés
  • TypeScript : Angular est Ă©crit en TypeScript et l'impose (ou presque). Cela apporte un typage statique robuste, idĂ©al pour les grands projets d'entreprise.
  • SPA (Single Page Application) : Angular charge une seule page HTML (index.html) et gĂšre dynamiquement le contenu via JavaScript, sans rechargement de page.
  • Composants : L'UI est dĂ©coupĂ©e en blocs logiques et rĂ©utilisables appelĂ©s "Composants".
  • DI (Injection de DĂ©pendances) : Un concept central (empruntĂ© Ă  Java/Spring) pour gĂ©rer la crĂ©ation et l'injection des services.
1.2 Architecture : Blocs de construction
Schéma de l'Architecture

Une application Angular est un arbre de Composants, organisés en Modules (ou Standalone), alimentés par des Services.

[Image d'une architecture Angular]
+---------------------------------------------------+
| AppModule / bootstrapApplication                  | (Module Racine)
|   (Importe: RouterModule, HttpClientModule...)    |
|   (Fournit: UserService, AuthService...)          |
|   (Bootstrap: AppComponent)                       |
|   +---------------------------------------------+ |
|   | AppComponent (Composant Racine)             | |
|   |   <router-outlet>                           | |
|   |     |                                       | |
|   |     +--> [HomePage (Composant)]             | |
|   |     |                                       | |
|   |     +--> [UsersPage (Composant)]            | |
|   |            (Injecte: UserService)           | |
|   +---------------------------------------------+ |
+---------------------------------------------------+
Les 4 Piliers
PilierDescriptionExemple
ComposantContrĂŽle une partie de l'UI (Vue + Logique).UserListComponent
Module (NgModule)(Ancien) Regroupe des composants/services.AppModule, UserModule
ServiceLogique métier (ex: appel HTTP). Singleton.UserService
Injection (DI)Mécanisme qui "injecte" les Services dans les Composants.constructor(private s: ...)
1.3 Installation (Node.js & Angular CLI)
1. Prérequis : Node.js & NPM

Angular (comme React ou Vue) est un framework "build-time". Vous avez besoin de Node.js et NPM (ou Yarn/PNPM) pour **développer**, **builder** (compiler) et **servir** l'application en local.

Il est recommandé d'utiliser NVM (Node Version Manager) (voir le guide Node.js) pour installer une version LTS (Long Term Support) de Node.

nvm install --lts
nvm use --lts
node -v # (ex: v20.x.x)
npm -v
2. Installation de l'Angular CLI

L'Angular CLI (Command Line Interface) est l'outil indispensable pour gérer un projet Angular. Il s'installe "globalement".

# 'npm install -g' installe l'outil globalement
npm install -g @angular/cli

# Vérifier l'installation
ng --version
# (Affiche la version d'Angular CLI, Node, etc.)
1.4 Angular CLI : ng new & ng serve
ng new (Créer un projet)

Crée un nouveau squelette de projet.

ng new mon-projet-angular

L'installeur pose plusieurs questions :

  • Would you like to add Angular routing? (Voulez-vous le routage ?) -> Yes.
  • Which stylesheet format? (CSS, SCSS, Sass, Less) -> SCSS (recommandĂ©) ou CSS.

Moderne (Angular 17+) : Par défaut, ng new crée une application Standalone (sans NgModules, voir 2.3). Pour l'ancien format (Modules) :

ng new mon-projet-angular --standalone=false
ng serve (Lancer le serveur de dev)

Compile l'application en mémoire et lance un serveur de dev (avec "Hot Reload").

cd mon-projet-angular
npm install # (Si nécessaire)

# Lancer le serveur
ng serve

# (ou 'ng serve --open' pour ouvrir le navigateur)
# (ou 'ng s')

Serveur de dev lancé sur http://localhost:4200/.

ng generate (Générer des "Blueprints")

La force de la CLI : générer les fichiers (et les lier).

# Syntaxe: ng generate [blueprint] [nom]
# (ou 'ng g [blueprint] [nom]')

# Générer un Composant (Crée .ts, .html, .css, .spec.ts)
ng generate component components/MonBouton
# (ou 'ng g c components/MonBouton')

# Générer un Service
ng generate service services/Utilisateur
# (ou 'ng g s services/Utilisateur')

# Générer un Module (ancien)
ng g m mon-module

# Générer un Guard (routage)
ng g guard auth/AuthGuard
2.1 Anatomie d'un Composant
src/app/user-profile/user-profile.component.ts

Le Décorateur @Component lie la classe (logique) au template et au style.

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common'; // (Pour ngIf, ngFor...)

@Component({
  selector: 'app-user-profile', // 1. Nom de la balise HTML
  standalone: true, // 2. (Moderne) Composant Standalone
  imports: [CommonModule], // 3. (Moderne) Importe les dépendances
  templateUrl: './user-profile.component.html', // 4. Lien vers le HTML
  styleUrls: ['./user-profile.component.css'] // 5. Lien vers le CSS
})
export class UserProfileComponent {

  // 6. Propriétés (le "State")
  utilisateur = {
    nom: "Alice",
    age: 30
  };
  
  // 7. Méthodes (les événements)
  feterAnniversaire() {
    this.utilisateur.age++;
    // (Pas besoin de 'setState', Angular détecte le changement)
  }
}
user-profile.component.html

Le template utilise la syntaxe Angular (interpolation, bindings).

<!-- 1. Interpolation (Binding One-Way) -->
<h1>Profil de </h1>

<p>Âge : </p>

<!-- 2. Event Binding (click) -->
<button (click)="feterAnniversaire()">
  FĂȘter l'anniversaire
</button>
Utilisation (dans app.component.html)
<h1>Mon App</h1>
<!-- Utilise le 'selector' (cf .ts) -->
<app-user-profile></app-user-profile>
user-profile.component.css

Par défaut, les styles sont **scopés** (encapsulés). Ils ne s'appliquent *qu'à ce composant* et ne "fuient" pas.

h1 {
  color: blue;
  /* Ce 'h1' ne s'applique QU'AU h1 de UserProfile,
     pas au h1 de AppComponent */
}

Comment ? Angular ajoute un attribut unique Ă  l'HTML et au CSS :

<!-- Rendu HTML -->
<h1 _ngcontent-c1="">Profil de Alice</h1>

/* Rendu CSS */
h1[_ngcontent-c1] {
  color: blue;
}
2.2 @NgModule (L'ancien systĂšme)
Concept (Avant Angular 15)

Avant les composants "Standalone", tout devait ĂȘtre dĂ©clarĂ© dans un @NgModule (Module).

Un Module est une "boßte" qui regroupe un ensemble de fonctionnalités (Composants, Services...). AppModule est le module racine.

Anatomie (app.module.ts)
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';

import { AppComponent } from './app.component';
import { UserProfileComponent } from './user-profile/user-profile.component';
import { UserService } from './services/user.service';

@NgModule({
  
  // 1. Choses créées DANS ce module (Composants, Pipes)
  declarations: [
    AppComponent,
    UserProfileComponent
  ],
  
  // 2. Choses importées (Autres Modules)
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  
  // 3. Services (Injection de Dépendances)
  providers: [
    UserService
  ],
  
  // 4. Le composant racine
  bootstrap: [AppComponent]
})
export class AppModule { }
2.3 Composants Standalone (Le standard moderne)
La fin des @NgModule

Depuis Angular 15 (et par dĂ©faut dans 17+), les @NgModule sont optionnels. Les composants peuvent ĂȘtre "Standalone" (autonomes).

Un composant Standalone gĂšre ses propres dĂ©pendances (via imports) sans avoir besoin d'ĂȘtre "dĂ©clarĂ©" dans un module.

C'est plus simple et plus proche de React/Vue.

Exemple (user-profile.component.ts)
import { Component } from '@angular/core';
// On importe les briques nécessaires
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';

@Component({
  selector: 'app-user-profile',
  
  // 1. Devient Standalone
  standalone: true,
  
  // 2. Importe ses propres dépendances
  //    (l'équivalent du 'imports' de @NgModule)
  imports: [
    CommonModule, // (*ngIf, *ngFor)
    RouterModule  // (routerLink)
  ],
  
  templateUrl: '...',
  styleUrls: [...]
})
export class UserProfileComponent {
  // ...
}
2.4 Templates : Data Binding
1. Interpolation {{ }}

Affiche une valeur (String, Number) du .ts dans le .html.

// component.ts
titre = "Mon Application";
// component.html
<h1>{{ titre }}</h1>
<p>Calcul : {{ 10 + 5 }}</p>
2. Property Binding [ ] (One-Way: TS -> HTML)

Lie une propriété du .ts à un **attribut HTML** (ex: disabled, src, href).

// component.ts
isDisabled = true;
logoUrl = "/logo.png";

// component.html
<button [disabled]="isDisabled">Cliquez</button>
<img [src]="logoUrl">
<a [href]="'https://site.com/' + userId">Lien</a>
3. Event Binding ( ) (One-Way: HTML -> TS)

Lie un **événement DOM** (ex: click, submit) à une **méthode** du .ts.

// component.ts
onSauvegarder() {
  console.log("Sauvegardé !");
}

// component.html
<button (click)="onSauvegarder()">Sauver</button>
4. Two-Way Binding [( )] ("Banana in a box")

Utilisé pour les formulaires. Combine [ ] (mise à jour du champ) et ( ) (écoute du changement).

Nécessite FormsModule ou ReactiveFormsModule.

// component.ts
username = "Alice";

// component.html
<input [(ngModel)]="username">
<p>Bonjour, {{ username }}</p>
// (Si l'utilisateur tape, 'username' et le <p> se mettent Ă  jour)
2.5 Directives (*ngIf, *ngFor, @if, @for)
Nouvelle Syntaxe (Control Flow) (Angular 17+)

Plus besoin d'importer CommonModule dans les composants Standalone.

@if (Conditionnel)
<h1>Bienvenue</h1>
@if (user) {
  <p>Bonjour, {{ user.nom }}</p>
} @else if (isLoading) {
  <p>Chargement...</p>
} @else {
  <a routerLink="/login">Connexion</a>
}
@for (Boucle)
<ul>
  @for (item of items; track item.id; let i = $index) {
    <li>({{ i }}) {{ item.nom }}</li>
  } @empty {
    <li>Aucun item trouvé.</li>
  }
</ul>
Ancienne Syntaxe (*ngIf, *ngFor)

Nécessite CommonModule dans les imports.

*ngIf
<!-- 'else' avec un  -->
<div *ngIf="user; else loadingTemplate">
  <p>Bonjour, {{ user.nom }}</p>
</div>
<ng-template #loadingTemplate>
  <p>Chargement...</p>
</ng-template>
*ngFor
<ul>
  <li *ngFor="let item of items; let i = index; trackBy: trackById">
    ({{ i }}) {{ item.nom }}</li>
</ul>
Directives d'Attribut (Style)

Modifient l'apparence ou le comportement d'un élément.

<!-- [ngClass] -->
<!-- Ajoute la classe 'active' SI isActive est true -->
<div [ngClass]="{ 'active': isActive, 'error': hasError }">
  ...
</div>

<!-- [ngStyle] -->
<!-- Applique le style SI isActive est true -->
<div [ngStyle]="{
  'color': isActive ? 'blue' : 'gray',
  'font-weight': 'bold'
}">
  ...
</div>
2.6 Pipes (|)
Formateurs de données

Un Pipe (|) est un formateur simple à utiliser dans un template pour transformer une donnée (date, nombre, string) à l'affichage.

// component.ts
aujourdhui = new Date(); // (Objet Date)
montant = 1234.56;
monObjet = { nom: "Test" };
monObservable$ = this.http.get(...);
Exemples (component.html)
ExempleRésultat
{{ aujourdhui | date:'dd/MM/yyyy' }}(ex: 02/11/2025)
{{ "Bonjour" | uppercase }}BONJOUR
{{ "Bonjour" | lowercase }}bonjour
{{ montant | currency:'EUR':'symbol' }}€1,234.56
{{ monObjet | json }}{ "nom": "Test" } (Debug)
{{ monObservable$ | async }}(GĂšre le subscribe/unsubscribe)
3.1 Services & Injection de Dépendances (DI)
Le ProblĂšme

Les Composants ne doivent pas contenir de logique mĂ©tier (ex: appels HTTP). Ils doivent ĂȘtre "bĂȘtes" et n'afficher que des donnĂ©es.

La logique mĂ©tier (fetch, calculs...) doit ĂȘtre dans un Service.

Le Service (Singleton)

Un Service est une simple classe TypeScript, marquée comme Singleton (il n'en existe qu'une seule instance pour toute l'application).

L'Injection de Dépendances (DI)

C'est le "ciment" d'Angular. Au lieu que le Composant crée (new) le Service, il le "demande" dans son constructeur. Angular (l'Injecteur) s'occupe de le trouver et de le lui "injecter".

Inversion de ContrÎle (IoC) : Le composant ne contrÎle pas ses dépendances, il les reçoit.

1. Le Service (user.service.ts)

@Injectable marque la classe comme "injectable". providedIn: 'root' en fait un Singleton global (la méthode moderne).

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class UserService {

  // (Le HttpClient sera lui-mĂȘme injectĂ© ici !)
  constructor(private http: HttpClient) { }
  
  getUsers() {
    return this.http.get('/api/users');
  }
  
  getOneUser(id: number) {
    return this.http.get(`/api/users/${id}`);
  }
}
2. Le Composant (user-list.component.ts)

Le composant "demande" le UserService via son constructeur.

import { Component, OnInit } from '@angular/core';
import { UserService } from '../services/user.service'; // Importer

@Component({
  selector: 'app-user-list',
  // ...
})
export class UserListComponent implements OnInit {
  
  users: any[] = [];
  
  // 1. INJECTION DE DÉPENDANCES
  // Angular voit "UserService" et injecte le singleton
  constructor(private userService: UserService) { }

  // 2. OnInit (Hook de cycle de vie)
  //    (Appelé une fois aprÚs le 1er rendu)
  ngOnInit(): void {
    // 3. Utiliser le service
    this.userService.getUsers().subscribe(data => {
      this.users = data;
    });
  }
}
3.3 Routage (RouterModule)
Définir les Routes (app.routes.ts)

Si vous avez dit "Yes" au routage lors du ng new, ce fichier est créé.

import { Routes } from '@angular/router';
import { HomePageComponent } from './pages/home-page.component';
import { AboutPageComponent } from './pages/about-page.component';
import { UserProfileComponent } from './pages/user-profile.component';

export const routes: Routes = [
  // Route simple
  { path: '', component: HomePageComponent },
  { path: 'about', component: AboutPageComponent },
  
  // Route avec paramĂštre
  { path: 'users/:id', component: UserProfileComponent },
  
  // Wildcard (Page 404)
  { path: '**', redirectTo: '' }
];
<router-outlet> (Le "Placeholder")

Dans votre app.component.html, <router-outlet> est l'endroit oĂč le composant de la route active sera affichĂ©.

<!-- app.component.html -->
<nav>
  <!-- 2. Liens de navigation -->
  <a routerLink="/">Accueil</a>
  <a routerLink="/about">À Propos</a>
</nav>

<!-- 1. Le composant (HomePage ou AboutPage) s'affichera ici -->
<router-outlet></router-outlet>
routerLink (La Navigation)

Utilisez routerLink (et non href) pour naviguer sans recharger la page (SPA).

<a routerLink="/users/10">Voir User 10</a>

<!-- Binding (si l'ID est dynamique) -->
<a [routerLink]="['/users', userId]">Mon Profil</a>
3.4 Routage Avancé (ParamÚtres & Guards)
Lire les ParamĂštres (ActivatedRoute)

Dans le composant (ex: UserProfileComponent), on écoute ActivatedRoute pour récupérer l'ID de l'URL.

// user-profile.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { switchMap } from 'rxjs/operators';

@Component(...)
export class UserProfileComponent implements OnInit {
  userId: string;
  
  constructor(private route: ActivatedRoute) { }
  
  ngOnInit(): void {
    // Écouter les changements de l'URL (Observable RxJS)
    this.route.paramMap.pipe(
      switchMap(params => {
        this.userId = params.get('id');
        // return this.userService.getOneUser(this.userId);
      })
    ).subscribe(user => {
      // ...
    });
  }
}
Route Guards (Protection)

Un "Guard" est une fonction qui protĂšge une route. (Ex: "L'utilisateur est-il admin ?").

ng g guard auth/Admin
// admin.guard.ts
import { CanActivateFn } from '@angular/router';
import { inject } from '@angular/core';
import { AuthService } from './auth.service';

export const adminGuard: CanActivateFn = (route, state) => {
  const authService = inject(AuthService); // DI moderne
  
  if (authService.isAdmin()) {
    return true; // OK
  }
  // Pas admin: Rediriger
  // const router = inject(Router);
  // return router.parseUrl('/login');
  return false; // Bloquer
};
// app.routes.ts
{
  path: 'admin',
  component: AdminPanelComponent,
  canActivate: [adminGuard] // ProtĂšge la route
}
4.1 HttpClient & RxJS
HttpClientModule

Le module HTTP natif d'Angular. Il utilise RxJS (Observables).

Setup (app.config.ts) (Moderne)
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient() // Fournit le HttpClient
  ]
};
Setup (app.module.ts) (Ancien)
@NgModule({
  imports: [
    BrowserModule,
    HttpClientModule // Importer le module
  ],
  ...
})
export class AppModule { }
Utilisation (Service)

On injecte HttpClient dans un Service.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class ApiService {
  
  constructor(private http: HttpClient) { }
  
  // 1. Retourne un Observable (pas les données)
  getUsers(): Observable<any[]> {
    return this.http.get<any[]>('/api/users');
  }
  
  postUser(data: any): Observable<any> {
    return this.http.post('/api/users', data);
  }
}
Utilisation (Composant)
// user-list.component.ts
export class UserListComponent implements OnInit {
  users: any[] = [];
  
  constructor(private api: ApiService) { }
  
  ngOnInit(): void {
    // 2. L'appel ne part que lors du .subscribe()
    this.api.getUsers().subscribe(data => {
      this.users = data;
    });
  }
}
4.2 RxJS & Observables
Observables (Streams)

RxJS est une librairie de programmation rĂ©active. C'est le cƓur d'Angular (HTTP, Router, Forms...).

Un **Observable** est un "flux" (stream) de données dans le temps. (Contrairement à une Promise qui ne donne qu'une seule valeur).

PromiseObservable
ValeurUnique (1 résultat)Multiple (N résultats)
Exécution"Eager" (chaude)"Lazy" (froide) (ne démarre qu'au .subscribe())
AnnulableNonOui (.unsubscribe())
UsageAppel HTTP simpleAppels HTTP, ÉvĂ©nements (clicks), WebSockets
| async Pipe (La bonne pratique)

Gérer les .subscribe() et .unsubscribe() manuellement est lourd. Le pipe | async gÚre tout pour vous.

user-list.component.ts
import { Component } from '@angular/core';
import { ApiService } from '../services/api.service';
import { Observable } from 'rxjs';

@Component(...)
export class UserListComponent {
  
  // 1. Stocker l'Observable lui-mĂȘme
  users$: Observable<any[]>;
  
  constructor(private api: ApiService) {
    // 2. Assigner l'Observable (pas de .subscribe() ici)
    this.users$ = this.api.getUsers();
  }
}
user-list.component.html
<!-- 3. Le pipe 'async' gĂšre le subscribe/unsubscribe -->
<ul *ngIf="users$ | async as users">
  <li *ngFor="let user of users">
    {{ user.nom }}
  </li>
</ul>
4.3 Formulaires (Template-driven)
Formulaires "Template-driven"

La logique est principalement dans le template HTML. Simple pour des formulaires basiques (login, contact).

Nécessite FormsModule (ou import { FormsModule } from '@angular/forms' en Standalone).

Exemple (login.component.html)
<!-- 1. Référence #loginForm="ngForm" -->
<form #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm)">
  
  <div>
    <label for="email">Email</label>
    <input
      type="email"
      id="email"
      name="email"
      [(ngModel)]="model.email"
      required
      email
      #emailInput="ngModel"
    >
    
    <!-- 2. Gestion des erreurs (touché, invalide) -->
    <div *ngIf="emailInput.invalid && (emailInput.dirty || emailInput.touched)">
      <small *ngIf="emailInput.errors?.['required']">Email requis.</small>
      <small *ngIf="emailInput.errors?.['email']">Email invalide.</small>
    </div>
  </div>
  
  <button type="submit" [disabled]="loginForm.invalid">OK</button>
</form>
4.4 Formulaires (Reactive)
Formulaires "Reactive"

La logique est dans le fichier TypeScript. Plus complexe, mais beaucoup plus puissant pour les formulaires dynamiques, la validation complexe, et les tests.

Nécessite ReactiveFormsModule (ou import { ReactiveFormsModule } from '@angular/forms').

contact.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component(...)
export class ContactComponent implements OnInit {
  contactForm: FormGroup;

  // 1. Injecter FormBuilder
  constructor(private fb: FormBuilder) { }
  
  ngOnInit(): void {
    // 2. Définir le modÚle du formulaire (la logique)
    this.contactForm = this.fb.group({
      nom: ['', [Validators.required, Validators.minLength(3)]],
      email: ['', [Validators.required, Validators.email]],
      message: ['']
    });
    
    // (On peut écouter les changements ici)
    this.contactForm.get('nom').valueChanges.subscribe(val => ...);
  }
  
  onSubmit() {
    console.log(this.contactForm.value);
  }
}
contact.component.html

Le HTML est "plus bĂȘte". Il se contente de lier les Ă©lĂ©ments au FormGroup.

<!-- 1. Lier le FormGroup -->
<form [formGroup]="contactForm" (ngSubmit)="onSubmit()">

  <div>
    <label>Nom</label>
    <!-- 2. Lier le FormControl -->
    <input formControlName="nom">
    
    <!-- 3. Gestion des erreurs (via le .ts) -->
    <div *ngIf="contactForm.get('nom')?.invalid &&
                contactForm.get('nom')?.touched">
      <small *ngIf="contactForm.get('nom')?.errors?.['required']">
        Nom requis.
      </small>
    </div>
  </div>
  
  <div>
    <label>Email</label>
    <input formControlName="email">
  </div>

  <button type="submit" [disabled]="contactForm.invalid">OK</button>
</form>
5.1 Build & Déploiement
1. ng build

La commande ng build (ou npm run build) compile l'application TypeScript/HTML/CSS en un ensemble de fichiers JavaScript statiques, optimisés et minifiés.

# Lance le build de production
ng build

# (Crée un dossier /dist/mon-projet-angular/)
mon-projet-angular/
└── dist/
    └── mon-projet-angular/
        ├── browser/
        │   ├── assets/
        │   ├── main.aB1cD2.js
        │   ├── polyfills.eF3gH4.js
        │   ├── styles.sS5jH6.css
        │   └── index.html
        └── server/ (Si SSR activĂ©)

C'est le contenu du dossier browser/ que vous déployez.

2. Déploiement Nginx (SPA)

Comme React, Angular est une SPA. Si l'utilisateur rafraĂźchit la page sur /users/10, Nginx doit ĂȘtre configurĂ© pour renvoyer index.html (qui lancera Angular, qui lira l'URL et affichera le bon composant).

# /etc/nginx/sites-available/mon-site-angular
server {
    listen 80;
    server_name angular-app.com;

    # Chemin vers votre dossier de build
    root /var/www/mon-projet-angular/dist/mon-projet-angular/browser;
    
    # Fichier d'index
    index index.html;

    location / {
        # Essaye de trouver le fichier, OU le dossier,
        # SINON, renvoie vers index.html
        try_files $uri $uri/ /index.html;
    }
}
6.1 Cheat-sheet (CLI & Lifecycle)
Angular CLI (ng)
# Installer/Mettre Ă  jour la CLI
npm install -g @angular/cli

# Créer un projet (Standalone)
ng new mon-app

# Servir (Dev)
ng serve # (ou 'ng s')

# Générer des fichiers
ng generate component MonComposant # (ou 'ng g c')
ng generate service MonService   # (ou 'ng g s')
ng generate module MonModule     # (ou 'ng g m')
ng generate guard MonGuard       # (ou 'ng g g')
ng generate pipe MonPipe         # (ou 'ng g p')

# Builder (Prod)
ng build
Hooks de Cycle de Vie (Composant)

Méthodes appelées automatiquement par Angular.

HookDescription
constructor()(JS) Injection de dépendances (DI).
ngOnChanges()Appelé quand une @Input (Prop) change.
ngOnInit()Le plus utilisé. Appelé 1x aprÚs le 1er rendu. Parfait pour le data-fetching.
ngDoCheck()Détection de changements (rare).
ngOnDestroy()Important. Appelé juste avant la destruction. Parfait pour unsubscribe() (Cleanup).
Syntaxe Template
{{ interpolation }}
[propertyBinding]
(eventBinding)
[(twoWayBinding)]
*ngIf="condition" (ou @if)
*ngFor="let item of items" (ou @for)