À propos de ce cours
Toute l’interface d’une application Angular est faite de composants. Découvrez leur structure (classe, template, styles), le rôle du décorateur @Component, les trois formes de sélecteur et l’encapsulation des styles, à travers un exemple complet et sept activités.
-
Objectifs
- Comprendre ce qu'est un composant (component) Angular et pourquoi toute l'interface d'une application en est faite
- Lire une page comme un arbre de composants: composant racine, parents et enfants
- Connaître les fichiers d'un composant et le rôle de chacun : classe, template, styles, test
- Expliquer les métadonnées du décorateur
@Component:selector,templateUrl/template,styleUrl/styles,imports - Utiliser les trois formes de sélecteur: élément, attribut et classe
- Afficher un composant dans un autre et comprendre que chaque balise crée une instance indépendante
- Comprendre l'encapsulation des styles et le cycle de vie de base (
constructor,ngOnInit) - Reconnaître et corriger les erreurs les plus fréquentes (
NG8001,NG2008,NG8023…)
-
Présentation
- Angular est un framework, écrit en TypeScript, qui sert à construire des applications web d'une seule page (SPA). Il est livré sous forme de bibliothèques (
@angular/core,@angular/router,@angular/forms…) que l'on importe dans son application. - Dans une application Angular, tout ce que l'utilisateur voit est produit par des composants. Un composant est un morceau d'interface autonome: il possède sa vue (HTML), son apparence (CSS) et son comportement (TypeScript).
- C'est vous qui décidez de la taille d'un composant : il peut représenter un simple bouton, une carte, un formulaire ou un écran entier. Plus un composant est petit et spécialisé, plus il est facile à comprendre, à tester et à réutiliser.
- On peut comparer les composants à des briques de construction : on assemble de petites briques (une carte de formation, un badge) pour en former de plus grandes (une liste, une page), jusqu'à l'application complète.
- Angular est un framework, écrit en TypeScript, qui sert à construire des applications web d'une seule page (SPA). Il est livré sous forme de bibliothèques (

-
Définition
Un composant est une classe TypeScript décorée avec @Component, associée à un template HTML qui définit sa vue et, facultativement, à des styles CSS. Angular l'affiche partout où l'on écrit son sélecteur dans un template.
- Un composant réunit donc trois éléments :
- une classe: les données (propriétés) et le comportement (méthodes) ;
- un template: le HTML affiché, enrichi par la syntaxe d'Angular (
{{ }},(click),@if…) qui le relie à la classe : c'est le data binding; - des métadonnées, fournies par le décorateur
@Component, qui indiquent à Angular que la classe est un composant, comment l'insérer dans une page et quels fichiers l'accompagnent.
- Un peu d'histoire : dans la documentation officielle, un composant est une directive avec un template. Les directives sans template (qui modifient le comportement d'une balise existante) sont étudiées plus loin dans le cours.
L'arbre des composants
- Une application part toujours d'un composant racine (root component). Dans un projet créé avec
ng new, il s'appelleApp, son sélecteur estapp-root, et il est démarré parsrc/main.ts:
// src/main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { App } from './app/app';
bootstrapApplication(App, appConfig)
.catch((err) => console.error(err));
<!-- src/index.html (extrait) -->
<body>
<app-root></app-root>
</body>
bootstrapApplication(App)cherche la balise<app-root>dansindex.htmlet la remplace par le composantApp.- Le template de
Appcontient à son tour les sélecteurs d'autres composants (l'en-tête, les cartes, le pied de page), qui peuvent eux-mêmes en contenir d'autres. Cette imbrication forme l'arbre des composants. - Un composant qui en affiche un autre est son parent; le composant affiché est son enfant. Cette relation sera essentielle dans la leçon Communication entre composants : le parent transmet des données à ses enfants, les enfants préviennent leur parent.

-
Préparer un projet de découverte
- Pour suivre les exemples, créer un nouveau projet à côté de votre projet
forma-plusdu TP 1 (voir Présentation de Angular CLI) :
- Pour suivre les exemples, créer un nouveau projet à côté de votre projet
ng new decouverte-composants --style=css --ssr=false
cd decouverte-composants
code .
- Ouvrir
src/app/app.ts. C'est déjà un composant :
import { Component, signal } from '@angular/core';
import { RouterOutlet } from '@angular/router';
@Component({
imports: [RouterOutlet],
selector: 'app-root',
styleUrl: './app.css',
templateUrl: './app.html',
})
export class App {
protected readonly title = signal('decouverte-composants');
}
- Deux mots nouveaux dans ce code :
signal()crée une valeur « réactive » qu'Angular surveille (les signaux sont étudiés plus loin) ;protectedindique que la propriété est réservée au composant et à son template, comme le recommande le guide de style d'Angular. Dans cette leçon, on utilise des propriétés simples pour se concentrer sur la structure du composant. - Vider le fichier
app.html(il contient la page d'accueil de démonstration d'Angular) et retirerRouterOutletdeapp.ts: on va construire notre propre page.
Générer un composant avec Angular CLI
- On ne crée pas les fichiers d'un composant à la main : la commande
ng generate component(abrégéeng g c) les crée avec le bon contenu et les bons noms.
ng generate component carte-formation
ng g c entete --inline-template --inline-style
ng g c pied-page
ng g c badge

- Les options les plus utiles :
| Option | Effet |
|---|---|
--inline-template (-t) |
le HTML est écrit dans le fichier .ts (propriété template), pas de fichier .html |
--inline-style (-s) |
le CSS est écrit dans le fichier .ts (propriété styles), pas de fichier .css |
--skip-tests |
pas de fichier .spec.ts |
--flat |
pas de dossier propre au composant : les fichiers sont créés directement dans le dossier courant |
--dry-run |
affiche les fichiers qui seraient créés, sans rien écrire : pratique pour vérifier un chemin |
ng g c formations/liste-formations |
crée le composant dans le sous-dossier src/app/formations/ |
- Conventions de nommage : le nom passé à la CLI est écrit en kebab-case (
carte-formation). La CLI en déduit le nom des fichiers (carte-formation.ts), le nom de la classe en PascalCase (CarteFormation) et le sélecteur avec le préfixe du projet (app-carte-formation).
Anatomie d'un composant
- La commande
ng g c carte-formationa créé un dossier contenant quatre fichiers :
| Fichier | Rôle | Contenu généré |
|---|---|---|
carte-formation.ts |
la classe et ses métadonnées @Component |
la classe vide CarteFormation |
carte-formation.html |
le template: la vue du composant | <p>carte-formation works!</p> |
carte-formation.css |
les styles propres au composant | vide |
carte-formation.spec.ts |
le test unitaire, lancé par ng test |
un test qui vérifie que le composant se crée |
- Voici le fichier
carte-formation.tstel que la CLI le génère :
import { Component } from '@angular/core';
@Component({
imports: [],
selector: 'app-carte-formation',
styleUrl: './carte-formation.css',
templateUrl: './carte-formation.html',
})
export class CarteFormation {}
- On le complète avec des propriétés (les données de la carte) et une méthode (réserver une place). Un accesseur
get completcalcule si la session est pleine :
// carte-formation.ts
import { Component } from '@angular/core';
@Component({
imports: [],
selector: 'app-carte-formation',
styleUrl: './carte-formation.css',
templateUrl: './carte-formation.html',
})
export class CarteFormation {
titre = 'Développement Angular';
dureeHeures = 120;
prix = 1200;
places = 3;
get complet(): boolean {
return this.places === 0;
}
reserver(): void {
if (this.places > 0) {
this.places--;
}
}
}
<!-- carte-formation.html -->
<article class="carte">
<h3>{{ titre }}</h3>
<p>{{ dureeHeures }} heures – {{ prix }} DT</p>
<p class="places">
@if (complet) {
Session complète
} @else {
Places restantes : {{ places }}
}
</p>
<button type="button" (click)="reserver()" [disabled]="complet">
Réserver
</button>
</article>
/* carte-formation.css */
.carte {
border: 1px solid #cbd5e1;
border-radius: 10px;
padding: 16px;
width: 240px;
background: #fff;
}
h3 { color: #dd0031; margin: 0 0 8px; }
.places { font-weight: bold; }
button {
background: #dd0031; color: #fff; border: none;
border-radius: 6px; padding: 6px 14px; cursor: pointer;
}
button:disabled { background: #94a3b8; cursor: not-allowed; }
- Dans le template, la classe et la vue sont reliées par le data binding:
{{ titre }}(interpolation) affiche la valeur d'une propriété de la classe ;(click)="reserver()"(liaison d'événement) appelle une méthode de la classe quand on clique ;[disabled]="complet"(liaison de propriété) donne à une propriété HTML la valeur d'une expression ;@if/@elseaffiche un bloc ou un autre selon une condition.
- Le template ne peut utiliser que ce que la classe possède : une faute de frappe comme
{{ titr }}est détectée à la compilation (TS2551: Property 'titr' does not exist on type 'CarteFormation'. Did you mean 'titre'?). Chaque syntaxe est détaillée dans les leçons sur le data binding.

-
Le décorateur @Component et ses métadonnées
@Componentest un décorateur (voir Présentation des décorateurs) : une fonction placée juste avant la classe, qui reçoit un objet de configuration. Sans lui,CarteFormationne serait qu'une classe TypeScript ordinaire.- Les propriétés de cet objet s'appellent les métadonnées du composant :
| Métadonnée | Rôle | Exemple |
|---|---|---|
selector |
le sélecteur CSS qui indique où insérer le composant dans un template | 'app-carte-formation' |
templateUrl |
chemin du fichier HTML du template | './carte-formation.html' |
template |
le template écrit directement dans le fichier .ts (à la place de templateUrl) |
`<h1>{{ nomCentre }}</h1>` |
styleUrl |
chemin d'un fichier CSS | './carte-formation.css' |
styleUrls |
tableau de plusieurs fichiers CSS (ancienne écriture, toujours valable) | ['./carte.css', './theme.css'] |
styles |
le CSS écrit directement dans le fichier .ts |
`h1 { margin: 0; }` |
imports |
les composants, directives et pipes utilisés dans le template | [Entete, CarteFormation] |
- Ce qui est obligatoire : un composant doit avoir un template, avec
templateoutemplateUrl(jamais les deux). Les styles sont facultatifs. Le sélecteur est presque toujours présent ; il n'est inutile que pour un composant affiché uniquement par le routeur (une page), ce que l'on verra avec le routage.
template ou templateUrl ?
- Le composant
Entetea été généré avec--inline-template --inline-style: tout tient dans un seul fichier. Les accents graves (backticks) permettent d'écrire le HTML et le CSS sur plusieurs lignes :
// src/app/entete/entete.ts
import { Component } from '@angular/core';
@Component({
imports: [],
selector: 'app-entete',
styles: `
header { background: #1e293b; color: #fff; padding: 16px 24px; }
h1 { margin: 0; font-size: 1.6rem; }
p { margin: 4px 0 0; color: #94a3b8; }
`,
template: `
<header>
<h1>{{ nomCentre }}</h1>
<p>{{ slogan }}</p>
</header>
`,
})
export class Entete {
nomCentre = 'FormaPlus';
slogan = 'Centre de formation professionnelle';
}
- Règle pratique : un template de quelques lignes peut rester dans le fichier
.ts; dès qu'il grandit, on utilise un fichier séparé, plus lisible et mieux pris en charge par l'éditeur (coloration, autocomplétion HTML). C'est le choix par défaut de la CLI.
-
Le sélecteur : où afficher le composant
- Le sélecteur s'écrit comme un sélecteur CSS. Angular accepte trois formes :
// 1. Élément (balise)
@Component({
selector: 'app-entete',
…
})
export class Entete {}
// Utilisation
// <app-entete />
// 2. Attribut
@Component({
selector: '[app-pied-page]',
…
})
export class PiedPage {}
// Utilisation
// <footer app-pied-page></footer>
// 3. Classe CSS
@Component({
selector: '.app-badge',
…
})
export class Badge {}
// Utilisation
// <span class="app-badge"></span>

- L'élément est la forme normale, celle que génère la CLI. Le préfixe (
app-par défaut, réglable dansangular.jsonavec"prefix") évite les conflits avec les balises HTML et avec les composants des bibliothèques. - L'attribut est utile quand la balise doit rester une vraie balise HTML : un
<footer>pour l'accessibilité, une ligne<tr>dans un tableau (un tableau n'accepte pas de balise inconnue entre<tbody>et<tr>). - La classe est rare pour un composant ; on la rencontre surtout dans du code ancien.
- Balise auto-fermante : depuis Angular 15.1, on peut écrire
<app-entete />au lieu de<app-entete></app-entete>, quand le composant n'a pas de contenu entre ses balises.
Afficher un composant dans un autre
- Pour qu'un parent affiche un enfant, il faut deux choses:
- importer la classe de l'enfant et l'ajouter au tableau
importsdu décorateur du parent ; - écrire le sélecteur de l'enfant dans le template du parent.
- importer la classe de l'enfant et l'ajouter au tableau
// src/app/app.ts
import { Component } from '@angular/core';
import { Entete } from './entete/entete';
import { CarteFormation } from './carte-formation/carte-formation';
import { PiedPage } from './pied-page/pied-page';
import { Badge } from './badge/badge';
@Component({
imports: [Entete, CarteFormation, PiedPage, Badge],
selector: 'app-root',
styleUrl: './app.css',
templateUrl: './app.html',
})
export class App {}
<!-- src/app/app.html -->
<app-entete />
<main>
<h3>Nos formations <span class="app-badge"></span></h3>
<div class="cartes">
<app-carte-formation />
<app-carte-formation />
</div>
</main>
<footer app-pied-page></footer>
/* src/app/app.css */
main { padding: 16px 24px; }
.cartes { display: flex; gap: 16px; }
// src/app/pied-page/pied-page.ts
import { Component } from '@angular/core';
@Component({
imports: [],
selector: '[app-pied-page]',
styleUrl: './pied-page.css',
templateUrl: './pied-page.html',
})
export class PiedPage {
annee = new Date().getFullYear();
}
<!-- pied-page.html -->
<p>© {{ annee }} FormaPlus – Tous droits réservés</p>
// src/app/badge/badge.ts
import { Component } from '@angular/core';
@Component({
imports: [],
selector: '.app-badge',
styleUrl: './badge.css',
templateUrl: './badge.html',
})
export class Badge {
texte = 'Nouveau';
}
/* badge.css : :host désigne la balise du composant lui-même */
:host {
background: #16a34a; color: #fff;
border-radius: 999px; padding: 2px 10px; font-size: 0.8rem;
}
- Lancer
ng serveet ouvrirhttp://localhost:4200. Cliquer trois fois sur le bouton de la première carte, puis une fois sur celui de la seconde :

- Une balise = une instance. Chaque
<app-carte-formation />crée un nouvel objet de la classeCarteFormation, avec ses propres propriétés : réserver dans la première carte ne change rien à la seconde. - Les deux cartes affichent pour l'instant la même formation, car le titre est écrit dans la classe. Dans la leçon Communication entre composants, le parent transmettra à chaque carte sa formation avec
input(). - Si l'import est oublié, la compilation échoue avec l'erreur
NG8001. Angular indique le fichier, la ligne et la solution : ajouter le composant au tableauimports.

- L'inverse produit un avertissement : un composant présent dans
importsmais absent du template donneNG8113: Badge is not used within the template of App. Ce n'est pas bloquant, mais il faut retirer l'import inutile.
L'encapsulation des styles
- Le fichier
carte-formation.csscolore les titresh3en rouge. Pourtant, le titre « Nos formations », qui est aussi unh3mais appartient au template deApp, reste noir. - Angular isole les styles de chaque composant : il ajoute un attribut unique (
_ngcontent-…) à toutes les balises du template du composant et réécrit chaque règle CSS du composant avec cet attribut. Ouvrir les outils de développement du navigateur (F12, onglet Éléments) pour le constater :

- Conséquences pratiques :
- on peut écrire des sélecteurs simples (
h3,button,.carte) dans un composant sans risque de modifier le reste de l'application ; - la balise du composant elle-même (
<app-carte-formation>) se stylise avec le sélecteur spécial:host(voirbadge.css) ; - les styles communs à toute l'application (police, couleur de fond, Bootstrap) vont dans
src/styles.cssou dansangular.json, comme dans le TP 1.
- on peut écrire des sélecteurs simples (
Le cycle de vie en bref
- Angular crée, met à jour et détruit les composants. À certaines étapes, il appelle des méthodes de la classe, appelées hooks du cycle de vie. Les deux premières à connaître :
import { Component, OnInit } from '@angular/core';
@Component({ … })
export class CarteFormation implements OnInit {
constructor() {
console.log('1. constructor : la classe est créée');
}
ngOnInit(): void {
console.log('2. ngOnInit : le composant est prêt');
}
}
# Console du navigateur (2 cartes)
1. constructor : la classe est créée
1. constructor : la classe est créée
2. ngOnInit : le composant est prêt
2. ngOnInit : le composant est prêt
| Méthode | Appelée… | Usage |
|---|---|---|
constructor() |
à la création de l'objet | initialiser des propriétés simples, récupérer des services avec inject() |
ngOnInit() |
une fois, quand Angular a préparé le composant et ses données d'entrée | charger des données, démarrer un traitement |
ngOnDestroy() |
juste avant la suppression du composant | arrêter un minuteur, se désabonner |
- Pourquoi
implements OnInit? L'interfaceOnInitoblige la classe à écrire correctementngOnInit(): une faute de frappe (ngOninit) serait signalée par le compilateur au lieu d'être ignorée en silence (voir Les interfaces de classe en TypeScript).
Anciennes et nouvelles écritures
- Angular a beaucoup évolué. Les tutoriels et les projets anciens que vous rencontrerez utilisent souvent une autre écriture. Voici comment les reconnaître :
| Élément | Ancienne écriture | Écriture actuelle |
|---|---|---|
| Noms de fichier et de classe | app.component.ts, AppComponent |
app.ts, App (depuis Angular 20) |
| Déclaration des composants | tableau declarations d'un NgModule (app.module.ts) |
composants autonomes (standalone, par défaut depuis Angular 19) et tableau imports de chaque composant |
| Un fichier de styles | styleUrls: ['./app.component.css'] |
styleUrl: './app.css' |
| Conditions dans le template | <p *ngIf="complet"> |
@if (complet) { … } |
| Balise vide | <app-entete></app-entete> |
<app-entete /> |
- Le composant suivant, écrit pour une ancienne version d'Angular, fonctionne toujours, à condition que le fichier
app.component.cssexiste :
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'exemple';
}
-
Bonnes pratiques
- Un composant, une responsabilité : une carte affiche une formation, une liste affiche des cartes. Si un template dépasse une centaine de lignes, c'est souvent le signe qu'il faut le découper.
- Toujours générer avec la CLI (
ng g c) : les noms, le préfixe et le test sont cohérents. - Ranger par fonctionnalité :
layout/entete,layout/pied-page,formations/liste-formations,formations/carte-formation, comme dans le TP 1. - Garder la logique dans la classe et un template simple : pas de calcul compliqué dans
{{ }}, mais une méthode ou un accesseur (get complet). - Lire les messages du compilateur : les erreurs Angular indiquent le fichier, la ligne, et souvent la solution.
-
Activité 1 : générer et afficher un composant
- Dans le projet
decouverte-composants, reproduire les composants de la leçon :Entete,CarteFormation,PiedPageetBadge, puis les afficher dansApp. - Générer un composant
presentationqui affiche un paragraphe de présentation du centre, avec une propriétéanneeCreation = 2010et l'âge du centre calculé par un accesseurget anciennete(). L'afficher entre l'en-tête et la liste des cartes. - Vérifier avec
ng buildqu'il n'y a ni erreur ni avertissement.
- Dans le projet
-
Activité 2 : les trois formes du sélecteur
- Changer le sélecteur de
Badgeen attribut ([app-badge]) et adapterapp.html. Le badge s'affiche-t-il toujours ? - Donner à
PiedPagele sélecteurapp-entete, puis compiler. Noter le message obtenu (NG8023) et expliquer pourquoi Angular refuse. Revenir au sélecteur d'origine. - Expliquer en une phrase pourquoi on choisit le sélecteur d'attribut pour un composant qui représente une ligne
<tr>d'un tableau.
- Changer le sélecteur de
-
Activité 3 : template et styles en ligne ou séparés
- Transformer
Entetepour qu'il utilise des fichiers séparés : créerentete.htmletentete.css, y déplacer le HTML et le CSS, et remplacertemplateetstylespartemplateUrletstyleUrl. - Faire l'inverse pour
Badge: template et styles en ligne, puis supprimer ses fichiers.htmlet.css. - Mettre volontairement un mauvais nom de fichier dans un
templateUrlet noter le message (NG2008: Could not find template file …).
- Transformer
-
Activité 4 : propriétés et méthodes
- Dans
CarteFormation, ajouter une constantecapacite = 3, une méthodeannuler()qui rend une place (sans dépasser la capacité) et un deuxième bouton « Annuler », désactivé quand aucune place n'a été réservée. - Afficher le taux de remplissage avec un accesseur
get tauxRemplissage()(par exemple « 67 % »), arrondi avecMath.round. - Vérifier que les deux cartes restent indépendantes.
- Dans
-
Activité 5 : observer l'encapsulation
- Ouvrir les outils de développement (F12) et relever les attributs
_nghost-…et_ngcontent-…d'une carte et de l'en-tête. Les deux cartes ont-elles le même attribut ? Pourquoi ? - Ajouter
h3 { text-decoration: underline; }danssrc/styles.css. Quels titres sont soulignés ? Expliquer la différence avec la règleh3decarte-formation.css. - Dans
carte-formation.css, ajouter une règle:host { display: block; }et observer dans les outils de développement sur quelle balise elle s'applique.
- Ouvrir les outils de développement (F12) et relever les attributs
-
Activité 6 : lire les erreurs
- Provoquer une à une les erreurs suivantes, noter le message en commentaire dans votre code, puis corriger :
- retirer
CarteFormationdu tableauimportsdeApp(NG8001) ; - écrire
{{ titr }}dans le template de la carte (TS2551) ; - écrire
(click)="reserver"sans parenthèses (avertissementNG8111) ; - écrire
@if (complet())alors quecompletest un accesseur (TS6234) ; - supprimer le décorateur
@ComponentdeBadge(NG2012).
- retirer
- Provoquer une à une les erreurs suivantes, noter le message en commentaire dans votre code, puis corriger :
-
Activité 7 : retour sur le projet FormaPlus
- Dans votre projet
forma-plusdu TP 1, dessiner l'arbre des composants de la page d'accueil (sur papier ou dans leREADME.md) : composant racine, parents, enfants, avec leur sélecteur. - Générer un composant
accueil/temoignagesqui affiche deux avis de stagiaires dans des cartes Bootstrap, et l'insérer avant le formulaire de contact. - Faire un commit dans chaque dépôt :
git commit -m "Composants : activité N", puis un push.
- Dans votre projet
-
Erreurs fréquentes
| Message | Cause | Solution |
|---|---|---|
NG8001: 'app-x' is not a known element |
Composant utilisé dans un template sans être importé, ou faute de frappe dans le sélecteur | Ajouter la classe au tableau imports du parent ; vérifier le sélecteur |
NG8113: X is not used within the template of Y |
Composant importé mais jamais utilisé | Retirer l'import, ou utiliser le composant |
NG2008: Could not find template file './x.html'. |
Chemin de templateUrl incorrect |
Corriger le nom ou le chemin (relatif au fichier .ts) |
NG8023: Multiple components match node with tagname … |
Deux composants importés ont le même sélecteur | Donner un sélecteur unique à chaque composant |
NG2012: Component imports must be standalone components, directives, pipes, or must be NgModules. |
Une classe sans décorateur @Component placée dans imports |
Ajouter le décorateur, ou importer la bonne classe |
TS2551: Property 'x' does not exist on type 'Y'. Did you mean …? |
Le template utilise une propriété inexistante (faute de frappe) | Corriger le nom, ou ajouter la propriété à la classe |
NG8111: Function in event binding should be invoked |
(click)="reserver": la méthode n'est pas appelée |
Écrire (click)="reserver()" |
-
À retenir
- Un composant = une classe + un template + des styles facultatifs, réunis par le décorateur
@Component. - L'application forme un arbre de composants qui part du composant racine
App(app-root), démarré parbootstrapApplication. - On génère un composant avec
ng g c nom: fichiers.ts,.html,.csset.spec.ts. - Métadonnées principales :
selector,templateUrloutemplate,styleUrloustyles,imports. - Pour afficher un enfant : l'ajouter aux
importsdu parent et écrire son sélecteur dans le template. Chaque balise crée une instance indépendante. - Les styles d'un composant sont encapsulés: ils ne s'appliquent qu'à son template.
ngOnInit()est appelée une fois, quand le composant est prêt.
- Un composant = une classe + un template + des styles facultatifs, réunis par le décorateur
Penser Angular, c'est penser en composants : avant d'écrire une ligne de code, découpez l'écran en morceaux, nommez-les, et dessinez leur arbre.