Bootstrap avec
Angular 18
Guide Complet
14/06/2024
Bootstrap est le plus connu et le
plus utilisé des Frameworks
CSS.
Nous allons
intégrer Bootstrap version
5.3.3 dans notre Application
Web.
Nous utiliserons pour cela le
framework
javascript Angular version
18.0.2
[Link]
Ce que nous allons faire
Qu'est-ce que Bootstrap ?
Nous allons parler de bootstrap et de son utilité dans les sites Web.
Création de notre projet Angular
Nous utiliserons un projet existant contenant les fonctionnalités essentielles.
Le projet a été généré avec Angular CLI et utilise le Routing et le Lazy Loading.
Prototype Bootstrap
Pourquoi et comment créer un prototype Bootstrap ?
Version 4 versus Version 5
Quelle version de bootstrap devriez-vous choisir ?
Intégration à notre projet angular
Comment intégrer Bootstrap en utilisant Angular CLI ?
Effectuer les Tests
Nous testerons notre application via les tests unitaires et end-to-end intégrés
dans Angular.
Code source
Pour les plus pressés d'entre vous, le code complet du projet.
[Link]
Qu’est-ce que Bootstrap?
Les pages d'un site web sont écrites en utilisant 3 langages
informatiques (computer language en anglais)
Le langage HTML
HyperText Markup Language (Langage de Balisage HyperText)
il permet de créer et de représenter le contenu d'une page web et sa
structure
Le langage CSS
Cascading Style Sheets (Feuilles de style en cascade)
il est utilisé pour décrire la présentation d'une page
Le langage Javascript
Il permet de créer des fonctionnalités interactives dans la page.
De nombreux outils permettent de simplifier la vie d'un développeur.
Notamment les Frameworks CSS qui constituent en quelque sorte des boites à
outils graphiques.
Les Framework CSS sont extrêmement nombreux, parmi ceux-ci nous
pourrions citer
Foundation
Materialize CSS
Bootstrap
Pure
Bootstrap est l'un des framework CSS les plus connus et les plus utilisés.
Bootstrap est sous licence open source depuis 2011.
Son utilisation est donc gratuite.
La version actuelle est la version 5.3.1
Création du projet
Pour pouvoir continuer ce tutoriel nous devons bien évidemment disposer de
certains éléments
[Link] : La plateforme javascript
Git : Le logiciel de gestion de versions.
Angular CLI : L'outil fourni par Angular.
Visual Studio code : Un éditeur de code.
Vous pouvez consulter le tutoriel suivant qui vous explique en détails comment
faire
[Link]
Nous allons utiliser un projet existant dont les caractéristiques sont
Genéré avec Angular CLI
Routing
Lazy loading
Vous pouvez installer ce projet sur votre poste de travail en utilisant les
commandes suivantes.
# Créez un répertoire demo (le nom est ici arbitraire)
mkdir demo
# Allez dans ce répertoire
cd demo
# Récupérez le code source sur votre poste de travail
git clone [Link]
# Allez dans le répertoire qui a été créé
cd angular-lazy-loading
cd angular
# Exécutez l'installation des dépendances (ou librairies)
npm install
# Exécutez le programme
npm run start
# Vérifiez son fonctionnement en lançant dans votre navigateur la commande
[Link]
Pourquoi Créer un prototype Bootstrap ?
En simplifiant il y a 3 types de développeur Web
Frontend
Backend
Fullstack
On pourrait rajouter un 4ème métier
Web Designer
Toujours en simplifiant, les 3 premiers s'occupent de la partie logique et le
quatrième de la partie graphique.
C'est pour cela que nous allons créer tout d'abord un prototype graphique.
Ce prototype servira de base à la phase de conception de votre site web.
Quelques raisons de ce choix.
Il est plus difficile et coûteux de faire des changements dans le code
plutôt que dans un prototype.
Si vous êtes amené à travailler en équipe, il est plus facile de savoir qui
fait quoi.
Il existe de nombreux outils de prototypage.
Il facilite l’évolution et l'amélioration de l’interface.
Il est plus rapide et facile de présenter un prototype à un éventuel client.
Donc.
Pour se faire, il n'est pas utile de connaitre Angular.
Seule la connaissance de HTML,CSS et d'un peu de javascript sera nécessaire.
Il sera même possible de sous-traiter à un partenaire Web Designer ou
graphiste.
Ce sont certains des éléments de ce prototype que nous intégrerons à notre
application Angular.
L'architecture de ce prototype et le choix des noms est bien sûr arbitraire.
Vous pouvez l'adapter à votre convenance.
Rapide résumé du prototypage ?
La conception d’un site web passera par plusieurs étapes.
L’une d’entre elles est le prototypage.
Le prototypage consiste à créer un exemplaire non définitif de ce que pourra
être le produit final.
Il permet de concevoir une Interface Utilisateur ou UI (User Interface)
Il existe 2 étapes de prototypage.
Prototypage horizontal
Créer une maquette statique.
Dessiner un schéma (wireframe)
Définir les zones et composants
Prototypage vertical
Intégrer les fonctionnalités
Nous allons dans le cadre de ce tutoriel créer simplement une maquette
statique.
Comment créer un prototype Bootstrap?
Histoire de comprendre ce que l'on fait, nous n'utiliserons aucun outil de
prototypage.
Nous concevrons ce prototype manuellement et à partir de rien (from scratch).
Le répertoire qui contiendra ce prototype sera UI ou User Interface (pour
Interface Utilisateur).
Une image va nous permettre d'avoir une vue d'ensemble de notre prototype au
sein de notre application Angular.
Passons à la pratique.
Nous allons chercher sur le web tous les éléments nécessaires que nous
placerons dans l'arborescence de notre projet Angular.
Nous obtiendrons au final l'arborescence suivante.
|-- node_modules/ (contient les librairies node)
|-- src/ (contient le code source de notre application angular)
|-- ui/ ( contient notre prototype bootstrap)
|-- assets
|-- bootstrap
|-- css
|-- js
|-- fontawesome
|-- css
|-- js
|-- webfonts
|-- params
|-- css
|-- images
|-- js
[Link]
Version 4 vs Version 5
Bootstrap 4 c'est bien sympa.
Mais la version 5 est sortie.
Il s'agit de la version 5.3.3
Il est intéressant de voir que cette version apporte quelques
modifications majeures.
La suppression de Jquery.
Et par conséquent l'utilisation de vanilla javascript (autrement dit du
javascript rien que du javascript)
L'abandon de la compatibilité avec IE 10 et 11 (Internet Explorer)
C'était pas trop tôt
Le projet final utilisera la version 5, j'ai testé, ça marche, alors pourquoi pas !
Au diable la prudence.
On aura le temps d'être prudent quand on sera mort.
Les éléments du prototype
Donc commençons !
Dans le répertoire ui créez un répertoire assets.
Dans ce répertoire assets créez les 3 répertoires suivants
bootstrap
fontawesome
params
Récupérons maintenant les différents éléments utiles à notre prototype.
Les éléments de bootstrap
Allez sur le site de bootstrap (partie donwload)
[Link]
Téléchargez les fichiers compilés CSS et JS (compiled CSS et
JS / download)
Le fichier qui nous intéresse est [Link]
Unzippez le fichier [Link]
Copiez les répertoires CSS et JS dans le répertoire ui / assets /
bootstrap
Les éléments de fontawesome
Allez sur le site de fontawesome (partie download)
[Link]
Download font Awesome free for the web
Téléchargez les fichiers compilés CSS et JS
Le fichier qui nous intéresse est [Link]
Unzippez le fichier [Link]
Copiez les répertoires CSS, JS et webfonts dans le répertoire ui /
assets / fontawesome
Remarque
Tous les fichiers installés ne seront pas utilisés.
Nous pouvons dans ce cas faire le ménage et ne laisser que l'essentiel.
Pour fontawesome nous ne garderons que les fichiers [Link] , [Link] et
[Link] et [Link]
Vous retrouverez le résultat final sur le dépôt du code source indiqué en fin de
tutoriel.
Dans le code source vous retrouverez le répertoire
ui (code bootstrap 5)
Notre première page Bootstrap
Nous allons créer notre première page en utilisant un exemple proposé par
bootstrap.
Nous utiliserons Starter template sur la page des exemples
Version 5
[Link]
Arbitrairement je vous donne le résultat final d'une page exemple.
Les différentes parties suivent.
Style Body
<style>
body {
padding-top: 3.5rem;
font-family: "Roboto", sans-serif;
}
</style>
Style Header
<style>
.[Link]-dark .navbar-nav .nav-item .nav-link {
color: white;
font-weight: 500;
border-top: 1px solid #09238d;
border-bottom: 1px solid #09238d;
}
.[Link]-dark .navbar-nav .nav-item .nav-link:hover {
color: yellow;
border-top: 1px solid yellow;
border-bottom: 1px solid yellow;
}
.nga-navbar {
-webkit-box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 11px
10px 0 rgba(0, 0, 0, 0.12);
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 11px 10px 0
rgba(0, 0, 0, 0.12);
background-color: #09238d;
}
.nga-logo {
font-weight: 700;
}
.nga-logo:hover {
color: rgba(255, 255, 255, 0.75);
}
.nga-btn-navbar {
color: #fff;
background-color: #1976d2;
border-color: #0d6efd;
}
.nga-btn-navbar:hover {
color: white;
background-color: #0b5ed7;
border-color: #0a58ca;
}
</style>
Style Footer
<style>
.nga-footer {
background-color: #212121;
color: white;
}
.nga-footer a {
color: white;
text-decoration: none
}
.nga-footer a:hover,
.nga-footer a:focus {
color: yellow;
text-decoration: underline;
}
.nga-footer .hint {
background-color: #1976d2;
}
.nga-footer .hint:hover {
opacity: 0.8;
}
</style>
Style Home
<style>
.nga-card {
display: block;
background-color: rgba(255, 255, 255, .8);
box-shadow: 0 1px 3px rgba(0, 0, 0, .12), 0 1px 2px rgba(0,
0, 0, .24);
border-radius: 2px;
transition: all .2s ease-in-out;
cursor: pointer;
}
.nga-card:hover {
box-shadow: 0 10px 20px rgba(0, 0, 0, .19), 0 6px 6px
rgba(0, 0, 0, .23);
}
</style>
Html Header
<header class="navbar navbar-expand-md navbar-dark fixed-top nga-navbar">
<nav class="container" aria-label="Main navigation">
<a href="" class="navbar-brand" alt="Accueil" aria-label="Ganatan">
<img src="./assets/params/images/logo/[Link]"
srcset="./assets/params/images/logo/[Link],
./assets/params/images/logo/ganatan-logo@[Link] 2x" width="25" height="25"
alt="Ganatan Logo">
<span class="nga-logo mx-1">ganatan</span>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-
target="#navbarCollapse"
aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav mx-auto">
<li class="nav-item">
<a class="nav-link" aria-current="page" href="">
<i class="fas fa-home me-1"></i>Home</a>
</li>
</ul>
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="">
<i class="far fa-question-circle me-1"></i>About</a>
</li>
<li class="nav-item">
<a class="nav-link" aria-current="page" href="">
<i class="fas fa-envelope me-1"></i>Contact</a>
</li>
</ul>
<form class="d-flex">
<button type="button" class="btn btn-sm nga-btn-navbar me-2"><i class="fas fa-user-
plus me-2"></i>Sign
up</button>
<button type="button" class="btn btn-sm btn-outline-light me-2"><i
class="fas fa-sign-in-alt me-2"></i>Login</button>
</form>
</div>
</nav>
</header>
Style Main
<main>
<div class="container py-5">
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-3 col-xl-3 text-center mb-2">
<h1 class="h5">
<i class="fas fa-laptop fa-lg me-2 text-primary"></i>
angular-starter
<i class="fas fa-mobile-alt fa-lg ms-2 text-primary"></i>
</h1>
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 text-center text-danger mb-2">
<h2 class="h5">
Angular 14.1.1<i class="fab fa-angular fa-lg ms-2"></i>
</h2>
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 text-center text-primary mb-2">
<h2 class="h5">
Bootstrap 5.2.0<i class="fab fa-bootstrap fa-lg ms-2"></i>
</h2>
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 text-center text-success mb-2">
<h2 class="h5">
Font Awesome 6.1.2<i class="fab fa-font-awesome-flag fa-lg ms-2"></i>
</h2>
</div>
</div>
<hr>
<div class="row mb-2">
<div class="col-md-12 text-center mb-4">
<h3 class="h5">Features<i class="fas fa-list ms-2"></i></h3>
</div>
</div>
</div>
</main>
Intégration de bootstrap dans Angular
Passons maintenant à la partie logique.
Nous allons faire fonctionner cette page home dans notre projet Angular de
base.
Tout d'abord il nous faut rajouter les librairies nécessaires.
On utilise pour cela npm (node package manager) le gestionnaire de
dépendances de [Link]
Pour bootstrap on suivra les conseils sur le site officiel.
[Link]
# Rajout des dépendances dans [Link]
npm install --save bootstrap@next
npm install --save @fortawesome/fontawesome-free
Comme nous l'avons vu dans le tutoriel Démarrer avec angular nous
modifierons les descripteurs de version de dépendances.
Concernant les dépendances et leur version la documentation npm est la
suivante
[Link]
Ce qui nous donnera le résultat suivant.
[Link]
"@fortawesome/fontawesome-free": "6.5.2",
"bootstrap": "5.3.3",
"rxjs": "7.8.1",
"tslib": "2.6.2",
"[Link]": "0.14.2"
Mise à jour
Réutilisons donc les éléments de notre prototype.
Copiez tout le répertoire params de notre prototype dans notre application
angular au niveau de src/assets
Nous allons modifier le fichier [Link] afin d'appeler les fichiers
nécessaires au fonctionnement de nos pages html.
Fichiers de mise en forme css
[Link] (spécifique à notre projet via params)
[Link] (spécifique à fontawesome via node_modules)
[Link] (spécifique à bootstrap via node_modules)
Fichiers des scripts javascript
[Link] (spécifique à jquery via node_modules)
[Link](spécifique à bootstrap via node_modules)
Remarque
Dans notre cas nous utiliserons le fichier [Link]
Nous pourrons alors utiliser les composants Bootstrap de
type Toasts ,Tooltips ou Popovers
La documentation est ici
[Link]
[Link]
[Link]
[Link]
Pour rajouter le code spécifique à notre projet ici
Remarque : Dans le cas de la version 5
Je préfère le rajouter sur [Link] en fin de chargement de page
et éviter les problèmes
Cela évite d'utiliser des fonctions du type [Link] par exemple
[Link]
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/angular-starter",
"index": "src/[Link]",
"main": "src/[Link]",
"polyfills": "src/[Link]",
"tsConfig": "[Link]",
"assets": [
"src/[Link]",
"src/assets"
],
"styles": [
"node_modules/@fortawesome/fontawesome-
free/css/[Link]",
"node_modules/bootstrap/dist/css/[Link]",
"src/assets/params/css/[Link]",
"src/[Link]"
],
"scripts": [
"node_modules/bootstrap/dist/js/[Link]"
]
},
src/assets/params/css/[Link]
body {
padding-top: 3.5rem;
font-family: "Roboto", sans-serif;
}
Nous allons modifier les fichiers suivants qui contiendront la nouvelle interface
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
Nous rajouterons les images utilisées dans le
répertoire assets/params/images/logo
[Link]
src/app/[Link]
<header class="navbar navbar-expand-md navbar-dark fixed-top nga-navbar">
<nav class="container" aria-label="Main navigation">
<a routerLink="/" class="navbar-brand" alt="Accueil" aria-label="Ganatan">
<img src="./assets/params/images/logo/[Link]"
srcset="./assets/params/images/logo/[Link],
./assets/params/images/logo/ganatan-logo@[Link] 2x" width="25" height="25" alt="Logo
Ganatan">
<span class="nga-logo mx-1">ganatan</span>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-
target="#navbarCollapse"
aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav mx-auto">
<li class="nav-item">
<a class="nav-link" aria-current="page" routerLink="/">
<i class="fas fa-home me-1"></i>Home</a>
</li>
</ul>
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link active" aria-current="page" routerLink="/about">
<i class="far fa-question-circle me-1"></i>About</a>
</li>
<li class="nav-item">
<a class="nav-link" aria-current="page" routerLink="/contact">
<i class="fas fa-envelope me-1"></i>Contact</a>
</li>
</ul>
<form class="d-flex">
<button type="button" class="btn btn-sm btn-primary me-2" routerLink="/signup"><i
class="fas fa-user-plus me-2"></i>Sign up</button>
<button type="button" class="btn btn-sm btn-outline-light me-2"
routerLink="/login"><i
class="fas fa-sign-in-alt me-2"></i>Login</button>
</form>
</div>
</nav>
</header>
<main>
<router-outlet></router-outlet>
</main>
<footer class="nga-footer">
<div class="py-3 text-center" style="background-color: black;">
<div class="container">
<a href="{{ footerUrl }}">{{ footerLink }}</a>
</div>
</div>
</footer>
src/app/[Link]
.[Link]-dark .navbar-nav .nav-item .nav-link {
color: white;
font-weight: 500;
border-top: 1px solid #09238d;
border-bottom: 1px solid #09238d;
}
.[Link]-dark .navbar-nav .nav-item .nav-link:hover {
color: yellow;
border-top: 1px solid yellow;
border-bottom: 1px solid yellow;
}
.nga-navbar {
-webkit-box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 11px 10px 0 rgba(0, 0, 0, 0.12);
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 11px 10px 0 rgba(0, 0, 0, 0.12);
background-color: #09238d;
}
.nga-navbar-logo {
font-weight: 700;
}
.nga-navbar-logo:hover {
color: rgba(255, 255, 255, 0.75);
}
.nga-logo {
font-weight: 700;
}
.nga-logo:hover {
color: rgba(255, 255, 255, 0.75);
}
.nga-footer {
background-color: #212121;
color: white;
}
.nga-footer a {
color: white;
text-decoration: none
}
.nga-footer a:hover,
.nga-footer a:focus {
color: yellow;
text-decoration: underline;
}
.nga-footer .hint {
background-color: #1976d2;
}
.nga-footer .hint:hover {
opacity: 0.8;
}
src/app/pages/general/home/[Link]
<div class="container py-5">
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-3 col-xl-3 text-center mb-2">
<h1 class="h5">
<i class="fas fa-laptop fa-lg me-2 text-primary"></i>
{{ name }}
<i class="fas fa-mobile-alt fa-lg ms-2 text-primary"></i>
</h1>
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 text-center text-danger mb-2">
<h2 class="h5">
{{ version }}<i class="fab fa-angular fa-lg ms-2"></i>
</h2>
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 text-center text-primary mb-2">
<h2 class="h5">
{{ bootstrap }}<i class="fab fa-bootstrap fa-lg ms-2"></i>
</h2>
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 text-center text-success mb-2">
<h2 class="h5">
{{ fontawesome }}<i class="fab fa-font-awesome-flag fa-lg ms-2"></i>
</h2>
</div>
</div>
<hr>
<div class="row mb-2">
<div class="col-md-12 text-center mb-4">
<h3 class="h5">Features<i class="fas fa-list ms-2"></i></h3>
</div>
</div>
<div class="row pt-2">
<div class="col-12 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2">
<div class="card nga-card bg-light mb-3">
<a routerLink="/bootstrap">
<div class="card-header">
<div class="row">
<div class="col-10 col-xl-10">
<h4 class="card-title h5">Bootstrap</h4>
</div>
<div class="col-2 col-xl-2">
<i class="fab fa-bootstrap fa-lg text-primary"></i>
</div>
</div>
</div>
<div class="card-body">
<p class="card-text">How to use Buttons, Alerts, Pagination, Tables, Collapses</p>
</div>
</a>
</div>
</div>
<div class="col-12 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2">
<div class="card nga-card bg-light mb-3">
<div class="card-header">
<div class="row">
<div class="col-10 col-xl-10">
<h4 class="card-title h5">Services</h4>
</div>
<div class="col-2 col-xl-2">
<i class="fas fa-handshake fa-lg text-primary"></i>
</div>
</div>
</div>
<div class="card-body">
<p class="card-text">Use services to view a playlist and a youtube player</p>
</div>
</div>
</div>
<div class="col-12 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2">
<div class="card nga-card bg-light mb-3">
<div class="card-header">
<div class="row">
<div class="col-10 col-xl-10">
<h4 class="card-title h5">Components</h4>
</div>
<div class="col-2 col-xl-2">
<i class="far fa-clone fa-lg text-primary"></i>
</div>
</div>
</div>
<div class="card-body">
<p class="card-text">Channel component with Input, Output and Event Emitter</p>
</div>
</div>
</div>
<div class="col-12 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2">
<div class="card nga-card bg-light mb-3">
<div class="card-header">
<div class="row">
<div class="col-10 col-xl-10">
<h4 class="card-title h5">Reactive Forms</h4>
</div>
<div class="col-2 col-xl-2">
<i class="far fa-file-alt fa-lg text-primary"></i>
</div>
</div>
</div>
<div class="card-body">
<p class="card-text">A model-driven approach to handling form inputs</p>
</div>
</div>
</div>
<div class="col-12 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2">
<div class="card nga-card bg-light mb-3">
<div class="card-header">
<div class="row">
<div class="col-10 col-xl-10">
<h4 class="card-title h5">Template Driven Forms</h4>
</div>
<div class="col-2 col-xl-2">
<i class="far fa-file-alt fa-lg text-primary"></i>
</div>
</div>
</div>
<div class="card-body">
<p class="card-text">Forms are the mainstay of business applications</p>
</div>
</div>
</div>
</div>
</div>
src/app/pages/general/home/[Link]
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterLink, RouterOutlet } from '@angular/router';
import { environment } from '../../../../environments/environment';
@Component({
selector: 'app-home',
standalone: true,
imports: [CommonModule, RouterLink, RouterOutlet],
templateUrl: './[Link]',
styleUrl: './[Link]'
})
export class HomeComponent {
name = [Link];
version = [Link];
bootstrap = [Link];
fontawesome = [Link];
}
src/app/pages/general/home/[Link]
.nga-card {
display: block;
background-color: rgba(255, 255, 255, .8);
box-shadow: 0 1px 3px rgba(0, 0, 0, .12), 0 1px 2px rgba(0, 0, 0, .24);
border-radius: 2px;
transition: all .2s ease-in-out;
cursor: pointer;
}
.nga-card:hover {
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(0, 0, 0, .19), 0 6px 6px rgba(0, 0, 0, .23);
}
.nga-card a {
color: black;
text-decoration: none;
}
.nga-card a:hover {
color: #0d6efd;
text-decoration: none;
}
src/app/pages/general/home/[Link]
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HomeComponent } from './[Link]';
import { RouterTestingModule } from '@angular/router/testing';
describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
beforeEach(async () => {
await [Link]({
imports: [HomeComponent, RouterTestingModule]
})
.compileComponents();
fixture = [Link](HomeComponent);
component = [Link];
[Link]();
});
it('should create', () => {
expect(component).toBeTruthy();
});
}); src/environments/[Link]
export const environment = {
application:
{
name: 'angular-bootstrap',
version: 'Angular 18.0.2',
bootstrap: 'Bootstrap 5.3.3',
fontawesome: 'Font Awesome 6.5.2',
}
};
src/environments/[Link]
export const environment = {
application:
{
name: 'angular-bootstrap',
version: 'Angular 18.0.2',
bootstrap: 'Bootstrap 5.3.3',
fontawesome: 'Font Awesome 6.5.2',
}
};
src/app/[Link]
import { TestBed } from '@angular/core/testing';
import { AppComponent } from './[Link]';
import { RouterTestingModule } from '@angular/router/testing';
describe('AppComponent', () => {
beforeEach(async () => {
await [Link]({
imports: [AppComponent, RouterTestingModule],
}).compileComponents();
});
it('should create the app', () => {
const fixture = [Link](AppComponent);
const app = [Link];
expect(app).toBeTruthy();
});
it(`should have the 'angular-routing' title`, () => {
const fixture = [Link](AppComponent);
const app = [Link];
expect([Link]).toEqual('angular-routing');
});
});
src/app/[Link]
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterLink, RouterOutlet } from '@angular/router';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, RouterLink, RouterOutlet],
templateUrl: './[Link]',
styleUrls: ['./[Link]']
})
export class AppComponent implements OnInit {
title = 'angular-routing';
footerUrl = '[Link]
footerLink = '[Link]';
ngOnInit(): void {
const navMain = [Link]('navbarCollapse');
if (navMain) {
[Link] = function onClick() {
if (navMain) {
[Link]("show");
}
}
}
}
}
src/app/pages/general/about/[Link]
<div class="row">
<div class="col-12 col-sm-12 col-md-3 col-lg-3 col-xl-3">
<p class="text-center">about works!</p>
<ul>
<li><a routerLink="/about/experience">experience</a></li>
<li><a routerLink="/about/skill">skill</a></li>
</ul>
</div>
<div class="col-12 col-sm-12 col-md-9 col-lg-9 col-xl-9">
<router-outlet></router-outlet>
</div>
</div>
src/app/pages/general/contact/[Link]
<div class="row">
<div class="col-12 col-sm-12 col-md-3 col-lg-3 col-xl-3">
<p class="text-center">contact works!</p>
<ul>
<li><a routerLink="/contact/mailing">Mailing</a></li>
<li><a routerLink="/contact/map">Map</a></li>
<li><a routerLink="/contact/website">Website</a></li>
</ul>
</div>
<div class="col-12 col-sm-12 col-md-9 col-lg-9 col-xl-9">
<router-outlet></router-outlet>
</div>
</div>
src/app/pages/general/signin/[Link]
<p class="text-center">signin works!</p>
src/app/pages/general/not-found/[Link]
<p class="text-center">not-found works!</p>
Composants
Le projet final intègre un module permettant de tester les composants de
Bootstrap.
Le code étant trop long je ne l'indique pas dans ce tutoriel.
Néanmoins le source complet est disponible sur Github.
Il est rajouté via le routing dans les fichiers suivants
[Link]
{
path: 'bootstrap',
loadChildren: () => import('./pages/application/example-bootstrap/[Link]')
.then(mod => [Link])
},
[Link]
Tests
Il ne reste plus qu'à tester les scripts suivants.
# Développement
npm run start
[Link]
# Test de la page not-found
[Link]
# Tests
npm run lint
npm run test
npm run e2e
# Production
npm run build
Code source
En suivant chacun des conseils que je vous ai donnés dans ce guide vous
obtenez au final un code source Angular.
Le code source obtenu à la fin de ce tutoriel est disponible sur github
[Link]
L' étape suivante va nous permettre d'améliorer notre structure.
Le tutoriel complet est à l'adresse suivante
Etape 5 : Modules avec Angular
Les étapes suivantes vous permettront d'obtenir une application prototype
Etape 6 : Server Side Rendering avec angular
Etape 7 : Progressive Web App avec Angular
Etape 8 : Search Engine Optimization avec Angular
Etape 9 : HttpClient avec Angular
La dernière étape permet d'obtenir un exemple d'application
Créer une application Web complète avec Angular
Le code source de cette application finale est disponible sur GitHub
[Link]