18-1 Réutilisation du formulaire de création
Essayons de réutiliser le même formulaire que la création, mais pour la modification aussi! Cela nous évitera de dupliquer une bonne partie de la logique de présentation.
Associer une route pour la modification
Premièrement, créez une route pour la modification vers le composant de création.
export const routes: Routes = [
{
path: '',
redirectTo: 'projets',
pathMatch: 'full'
},
{
path: 'projets',
component: ProjetsIndex
},
{
path: 'projets/creer',
component: ProjetCreer
},
{
path: 'projets/:id',
component: ProjetDetail
},
{
path: 'projets/:id/modifier',
component: ProjetCreer
}
];
Plusieurs routes peuvent pointer vers le même composant!
Faire un lien vers la page de modification à partir de ProjetDetailPage
Ajoutez un bouton Modifier
sur la page detail
pour accéder à la page de modification.
Des row
et col
ont été ajoutées pour disposer le contenu et aligner le bouton Modifier à droite du titre. Cela est optionnel, il s'agit simplement de positionnement et d'esthétisme visuel.
@Component({
selector: 'app-projet-detail',
imports: [
RouterLink
],
template: `
@if (projet) {
<div class="row">
<div class="col-lg-8">
<h1>{{projet.nom}}</h1>
</div>
<div class="col-lg-4 d-flex align-items-center justify-content-lg-end">
<a class="btn btn-secondary" [routerLink]="['/projets', projet.id, 'modifier']">Modifier</a>
</div>
</div>
<div class="row mt-3">
<div class="col">
<p>{{projet.description}}</p>
</div>
</div>
}
`,
styles: ``
})
Test dans le navigateur
Essayez d'appuyer sur le bouton Modifier
dans votre navigateur, vous devriez être dirigé vers la page de création.
Ne vous inquietez pas, nous verrons comment changer le texte faisant référence à la création pour supporter aussi la modification.
Charger les données du projet à modifier
Lors de la modification, il est important de charger le formulaire avec les données à modifier! Pour cela, lors de l'initialisation du composant, on peut utiliser la fonction de service obtenir()
.
Pour cela, on doit savoir si nous sommes en mode "édition" ou en mode "création". La facteur différentiation est la présence d'un id
de projet dans l'URL.
- Ajouter une propriété
projetId
pour stocker l'id du projet et détecter si nous sommes en mode édition au création.export class ProjetCreer {
projetForm = new FormBuilder().group({
nom: ['', [Validators.required, Validators.minLength(3)]],
description: [''],
}, {
updateOn : 'blur'
});
protected projetId: number | null = null; - Implémenter
OnInit
sur le composantexport class ProjetCreer implements OnInit {
projetForm = new FormBuilder().group({
nom: ['', [Validators.required, Validators.minLength(3)]],
description: [''],
}, {
updateOn : 'blur'
});
protected projetId: number | null = null;
get nom() {
return this.projetForm.get('nom');
}
get description() {
return this.projetForm.get('description')
}
constructor(private projetService: ProjetService,
private router: Router) { }
ngOnInit(): void {
} - Injecter la route active via
ActivatedRoute
constructor(private projetService: ProjetService,
private router: Router,
private route: ActivatedRoute) { } - Récupérer l'id lors de l'initialisation du composant
ngOnInit(): void {
const id = this.route.snapshot.paramMap.get('id');
if(id) {
this.projetId = +id;
}
} - Charger le projet si on a bel et bien un identifiant!
async ngOnInit(): Promise<void> {
const id = this.route.snapshot.paramMap.get('id');
if(id) {
this.projetId = +id;
await this.chargerProjet()
}
}
private async chargerProjet() {
if(this.projetId) {
const projet = await this.projetService.obtenir(this.projetId)
}
} - Vous pouvez regarder dans l'onglet réseau de votre navigateur, vous devriez avoir une requête d'API lors du chargement de la page en mode édition.
Préremplir le formulaire
Maintenant, remplissons le formulaire avec les données reçues. Pour cela, il existe une fonction patchValue
sur le formulaire.
private async chargerProjet() {
if(this.projetId) {
const projet = await this.projetService.obtenir(this.projetId)
this.projetForm.patchValue({
nom: projet.nom,
description: projet.description
})
}
}
patchValue
permet d'assigner des valeurs au formulaire via un objet. Le nom des propriétés doivent correspondre au nom des champs du formulaire.
Essayez de charger le formulaire de modification, vous devriez avoir les données du projet à modifier! 🎉
Mode édition vs. mode création
Il nous faut une façon de faire la distinction entre le mode édition et le mode création. En effet, le titre de la page doit être différent, le texte des boutons, en plus de l'action submit
.
- Ajouter une valeur booléenne
estModeEdition
au composant avecfalse
comme valeur par défaut.export class ProjetCreer implements OnInit {
projetForm = new FormBuilder().group({
nom: ['', [Validators.required, Validators.minLength(3)]],
description: [''],
}, {
updateOn : 'blur'
});
protected projetId: number | null = null;
protected estModeEdition: boolean = false; - Assignez une valeur de
true
au chargement si unid
est présent au niveau de la route.async ngOnInit(): Promise<void> {
const id = this.route.snapshot.paramMap.get('id');
if(id) {
this.projetId = +id;
this.estModeEdition = true;
await this.chargerProjet()
}
} - Modifier le titre de la page en mode édition
@Component({
selector: 'app-projet-creer',
imports: [
ReactiveFormsModule
],
template: `
<div class="row">
<div class="col-lg-6 offset-lg-3">
<h1>{{ estModeEdition ? 'Modifier le projet' : 'Créer un nouveau projet' }}</h1>
Nous avons une bonne ébauche de page réutilisant le même formulaire que la création, mais pour la modification!