Aller au contenu principal

10-3 Communication avec la vue via un ViewModel

Une autre approche, plutôt que le ViewBag, est d'utiliser un objet spécialement conçu pour la vue et contenant tout ce que cette dernière a besoin. Évidemment, si la vue n'a besoin que du modèle directement, on peut lui envoyer, mais si elle a besoin de plus, on crée alors un ViewModel.

info

Un ViewModel représente les données qu'on veut afficher et traiter dans la vue. Comme ici on veut afficher des événements et des villes, on peut créer un ViewModel qui contiendra deux propriétés:

  • Une liste d'événements (modèle Evenement)
  • Une liste de villes (modèle Ville)

Créer le ViewModel EvenementsIndexViewModel

  1. Créer un dossier Evenements sous le dossier Models du projet Web.Mvc. Puisque les modèles ont été déplacés dans un projet séparé, nous utiliserons le dossier Models du projet Web pour les ViewModels. Imgur

  2. Créer une classe EvenementsIndexViewModel. Sous le dossier Snowfall.Web.Mvc/Models/Evenements, créez une nouvelle classe EvenementsIndexViewModel.

    Snowfall.Web.Mvc/Models/Evenements/EvenementsIndexViewModel.cs
    namespace Snowfall.Web.Mvc.Models.Evenements;

    public class EvenementsIndexViewModel
    {

    }

Propriétés du ViewModel

Pour contenir les données que la vue aura besoin, des propriétés associées doivent exister dans le ViewModel.

La vue Index a besoin de 2 propriétés:

  • Une liste d'objets de type Evenement
  • Une liste d'objets de type Ville

Ajoutez ces deux listes à la classe EvenementsIndexViewModel:

Snowfall.Web.Mvc/Models/Evenements/EvenementsIndexViewModel.cs
using Snowfall.Domain.Models;

namespace Snowfall.Web.Mvc.Models.Evenements;

public class EvenementsIndexViewModel
{
public required List<Evenement> Evenements { get; set; }
public required List<Ville> Villes { get; set; }
}

Retourner un ViewModel à la vue

  1. Créez une liste de villes en mémoire dans l'action Index du contrôleur EvenementsController, que nous pourrons retourner à la vue. Nous aurons la chance de remplacer cette liste par une liste en provenance de la base de données bientôt.

    public async Task<IActionResult> Index()
    {
    List<Evenement> evenements = await _evenementService.GetAll();
    List<Ville> villes = new List<Ville>
    {
    new Ville
    {
    Id = 1,
    Nom = "Montreal",
    PaysIso = "CA"
    },
    new Ville
    {
    Id = 2,
    Nom = "Los Angeles",
    PaysIso = "US"
    }
    };

    return View(evenements);
    }
  2. Juste avant le retour de l'action Index(), créez une instance de EvenementsIndexViewModel contenant la liste de villes et d'événements, puis retournez ce nouveau modèle à la vue!:

    Snowfall.Web.Mvc/Controllers/EvenementsController.cs
    public async Task<IActionResult> Index()
    {
    List<Evenement> evenements = await _evenementService.GetAll();
    List<Ville> villes = new List<Ville>
    {
    new Ville
    {
    Id = 1,
    Nom = "Montreal",
    PaysIso = "CA"
    },
    new Ville
    {
    Id = 2,
    Nom = "Los Angeles",
    PaysIso = "US"
    }
    };

    var viewModel = new EvenementsIndexViewModel
    {
    Villes = villes,
    Evenements = evenements
    };

    return View(viewModel);
    }
    info

    À noter que le bloc suivant:

    Snowfall.Web.Mvc/Controllers/EvenementsController.cs
    var viewModel = new EvenementsIndexViewModel
    {
    Villes = villes,
    Evenements = evenements
    };

    Est équivalent à:

    Snowfall.Web.Mvc/Controllers/EvenementsController.cs
    var viewModel = new EvenementsIndexViewModel();
    viewModel.Villes = villes;
    viewModel.Evenements = evenements;

    On évite cependant de la répétition dans la première version et cette dernière est plus élégante. Ceci dit, il n'y a aucune différence au niveau de la fonctionnalité.