Tutoriel Angular / Spring / Java - partie 1
Tutoriel Angular / Spring / Java - partie 1
Dans cette série d'articles nous allons créer un Kanban basique. Le but étant de mettre en pratique la dernière version d'Angular (v8 au moment de rédaction de l'article), Spring pour le backend et PostgreSQL pour la partie bdd.
Par la suite nous ajouterons une fonctionnalité de chat pour rendre le dashboard plus pratique.
Le tutoriel est prévu pour Linux mais tout peut fonctionner sous Windows.
Prérequis :
- Nodejs
- Npm
- Visual Studio Code (ou un autre IDE comme IntelliJ)
Commençons par le setup basic
Le tuto nécessite npm installé en local globalement (cf le site de npm)
Installer ou mettre à jour npm
sudo npm install -g npm
Installer angular dans le projet :
sudo npm install -g @angular/cli
Créer un nouveau projet angular :
ng new kanban
(laisser les valeurs par défaut)Normalement voici l'arborescence à ce stade :
Actuellement le typescript du composant principal contient le minimum nécessaire :
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
On va lui ajouter un titre. Modifier app.component.html :
<div style="text-align:center">
<h1>
KANBAN
<img width="30" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
</h1>
</div>
Ajoutons des styles minimaux qui seront accessibles dans toute l'appli dans le fichier styles.css
/* Text */
h1 {
font-size: 32px;
}
h2 {
font-size: 20px;
}
h1, h2 {
font-weight: lighter;
}
p {
font-size: 14px;
}
/* Flex */
.flex-container {
display: flex;
}
.flex-container > div {
background-color: #f1f1f1;
width: 255px;
margin: 10px;
text-align: center;
line-height: 75px;
font-size: 30px;
}
Les cartes
Le kanban étant composé de trois cartes : TODO, DOING et DONE, créer un composant générique carte :
ng generate component carte
La CLI génère un composant vide dans le répertoire app/carte avec un template (component.html), une classe Typescript (component.ts) et un fichier css.
Remarquer que le composant a été ajouté par la CLI Angular dans les déclarations du module app.module.ts :
@NgModule({
declarations: [
AppComponent,
CarteComponent,
Ajoutons la balise carte dans le html principal :
<div class="flex-container">
<div>
<app-carte [carte]="TODO"></app-carte>
</div>
<div>
<app-carte [carte]="DOING"></app-carte>
</div>
<div>
<app-carte [carte]="DONE"></app-carte>
</div>
Ici, on voit que chaque app-carte possède un attribut [carte]. Il permet de passer à chaque composant un objet qui contiendra ses données : TODO, DOING et DONE.
On va remplir ces données plus tard.
Les tâches
Chaque carte aura un titre et un détail qui contiendra une liste de tâches. On va créer un composant réutilisable pour le détail de la carte :
ng generate component detail-carte
Comme précédemment la CLI génère le code minimal pour le composant.
Chaque composant détail devant afficher une liste de tâches, créons une classe Typescript Tache pour contenir ces données.
Créer un fichier tache.ts dans le répertoire src :
export class Tache {
id: number;
nom: string;
}
De même, créons une classe Carte qui contiendra les données d'un carte.
Créer un fichier carte.ts dans le répertoire src :
import { Tache } from './tache';
export class Carte {
id: number;
titre: string;
taches: Tache[];
}
Pour récupérer la liste des cartes et leur contenu, et pour le mettre à jour, on aura besoin d'un service.
Pour l'instant les données seront en dur dans le code. Créer un service 'kanban' pour ce faire :
ng generate service kanban
@Injectable({
providedIn: 'root'
})
export class KanbanService {
Ici providedIn: 'root' permet de rendre accessible le service à toute l'application (nous verrons le découpage en modules plus tard).
Données de test temporaires
Afin de rendre l'appli utilisable sans avoir créé le backend, il est nécessaire de fournir des données de test.
Créer le fichier mock.cartes.ts dans le dossier app :
import { Tache } from './tache';
import { Carte } from './carte';
export const cartes: Carte[] = [
{
id: 1,
titre: "TODO",
taches: [{
id: 1,
nom: "front"
}, {
id: 2,
nom: "back"
}]
},
{
id: 1,
titre: "DOING",
taches: [{
id: 3,
nom: "service liste"
}, {
id: 4,
nom: "service création"
}]
},
{
id: 1,
titre: "DONE",
taches: [{
id: 5,
nom: "BDD"
}, {
id: 6,
nom: "templates"
}]
}
];
Ceci nous permet retourner les données dans le service :
import { Injectable } from '@angular/core';
import { Carte } from './carte';
import { cartes } from './mock.cartes';
@Injectable({
providedIn: 'root'
})
export class KanbanService {
cartes: Carte[] = cartes;
constructor() { }
getCartes(): Carte[] {
return this.cartes;
}
}
Ces données, il va falloir les passer en paramètre aux trois composants. Pour ce faire, on va modifier le composant principal pour qu'il appelle le service, et qu'il stocke ces données :
import { Component, OnInit } from '@angular/core';
import { Carte } from './carte';
import { KanbanService } from './kanban.service';
import { Tache } from './tache';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
cartes: Carte[];
constructor(private kanbanService: KanbanService) { }
getKanban() {
this.cartes = this.kanbanService.getCartes();
this.TODO = this.cartes.find(carte => carte.titre === "TODO")
this.DOING = this.cartes.find(carte => carte.titre === "DOING")
this.DONE = this.cartes.find(carte => carte.titre === "DONE")
}
ngOnInit() {
this.getKanban();
}
TODO: Carte;
DOING: Carte;
DONE: Carte;
}
L'attribut [carte] dans app.component.html permet de passer les données à chaque carte.
Ensuite, modifier le composant carte pour lui passer ses données :
import { Input, Component, OnInit } from '@angular/core';
import { Carte } from '../carte';
import { Tache } from '../tache';
@Component({
selector: 'app-carte',
templateUrl: './carte.component.html',
styleUrls: ['./carte.component.css']
})
export class CarteComponent implements OnInit {
@Input() carte: Carte;
constructor() { }
ngOnInit() {
}
}
c'est l'annotation @Input() qui permet au composant de récupérer des données dans une variable.
Pour afficher les données de la carte, modifier carte.component.html :
<h1 class="titre">
{{carte.titre}}</h1>
<app-detail-carte carte.taches="" liste=""></app-detail-carte>
Enfin, modifier le composant de détail pour lui passer sa liste de tâches :
import { Input, Component, OnInit } from '@angular/core';
import { Tache } from '../tache';
@Component({
selector: 'app-detail-carte',
templateUrl: './detail-carte.component.html',
styleUrls: ['./detail-carte.component.css']
})
export class DetailCarteComponent implements OnInit {
@Input() liste: Tache[];
constructor() { }
ngOnInit() {
}
}
... et afficher chacune des tâches :
<div *ngFor="let tache of liste" class="tache">
<h2>
{{ tache.nom }}
</h2>
</div>
la syntaxe *ngFor permet de parcourir la liste des variables dans le tableau 'liste'
Questions de style
Chaque composant peut avoir droit à son css. On va s'en servir pour différencier le titre du reste de la liste.
Modifier carte.component.css :
.titre {
background-color: orange
}
Et detail-carte.component.css :
.tache {
font-family: 'Roboto', Arial, sans-serif;
color: #616161;
box-sizing: border-box;
}
Pour tester le site il suffit de lancer la commande :
ng serve
Voilà pour cette première étape : nous avons un site basique qui affiche une liste de tâches dans leurs cartes respectives :
Commentaires
Enregistrer un commentaire