Aller au contenu principal

2-7 Communiquer des données à la vue

Nous avons un contrôleur EvenementsController qui peut répondre aux requêtes en provenance de l'URL /evenements via la fonction Index().

De plus, dans ce même contrôleur, il existe un objet Evenement.

Et si nous voulions afficher cet évènement?

Rappel de la fonction View()

On se souvient que la fonction View() retourne un ViewResult permettant d'afficher une vue.

Eh bien, cette même fonction accepte d'autres paramètres!

Imgur

Pour le moment, la signature de fonction qui nous intéresse est la deuxième, soit object? model.

important

La fonction View() accepte un objet (model) en paramètre et cet objet est automatiquement passé à la vue.

Passer l'évènement à la vue

Modifiez l'appel à la fonction View() pour lui passer en paramètre l'objet événement:

Snowfall.Web.Mvc/Controllers/EvenementsController.cs
//...
return View(evenement);
//...

Exécuter le projet

Exécutez le projet (debug) et accédez à l'URL /evenements. Est-ce que quelque chose a changé?

Imgur

Arf, nous ne sommes pas tellement plus loin! Bien que nous passions l'objet à la vue, cette dernière ne sait pas quoi faire avec!

En effet, la vue Index ressemble toujours à ceci et n'a pas connaissance de l'objet passé en paramètre:

Snowfall.Web.Mvc/Views/Evenements/Index.cshtml
@{
ViewBag.Title = "title";
Layout = "_Layout";
}

<h2>title</h2>

Lier la vue au modèle

important

Bien que le contrôleur envoie à la vue le modèle évènement, cette dernière ne sait pas qu'elle doit recevoir un modèle de type Evenement en entrée, et surtout, elle ne contient rien d'autre qu'un titre.

Pour spécifier à la vue le type de modèle qu'elle recevra en entrée, on utilise @model dans le haut du fichier. Nous reviendrons à la signification de @ et à la syntaxe Razor.

Snowfall.Web.Mvc/Views/Evenements/Index.cshtml
@model Evenement;

@{
ViewBag.Title = "title";
Layout = "_Layout";
}

<h2>title</h2>

Récupérer des données du modèle

Finalement, pour récupérer et afficher les données du modèle, on peut faire référence dans le HTML au modèle lié à la vue via @Model.

Snowfall.Web.Mvc/Views/Evenements/Index.cshtml
@model Evenement;

@{
ViewBag.Title = "title";
Layout = "_Layout";
}

<h2>@Model.Nom</h2>

Comme nous avons spécifié dans le haut du fichier que le modèle associé à la vue était de type Evenement, cela nous permet d'avoir l'autocomplétion en utilisant @Model

Imgur

Afficher plus de détails

Affichons le reste des informations de l'évènement:

Snowfall.Web.Mvc/Views/Evenements/Index.cshtml
@model Evenement;

@{
ViewBag.Title = @Model.Nom;
Layout = "_Layout";
}

<h2>@Model.Nom</h2>
<p>@Model.Description</p>
<ul>
<li>Date: @Model.Date.ToShortDateString()</li>
<li>Capacité: @Model.Capacite</li>
<li>Prix: @Model.Prix</li>
</ul>

Vérifiez dans le navigateur, en lançant le projet, que vous obtenez bien les détails de l'évènement:

Imgur

ViewBag et ViewBag.Title

Mais à quoi sert ViewBag.Title dans la vue?

Si vous regardez attentivement le fichier _Layout.cshtml, vous verrez ceci:

Snowfall.Web.Mvc/Views/Shared/_Layout.cshtml
...
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>@ViewData["Title"] - Snowfall</title>
...

Le layout du site utilise des données de la vue pour construire le contenu de la balise title (texte affiché dans l'onglet et texte récupéré par Google et autres moteurs de recherche).

important

La variable ViewBag est en quelque sorte une varible globale accessible autant au niveau du contrôleur que de la vue et du layout. L'objet permet de passer des données qui sortent du contexte du modèle, comme un titre de page par exemple.

Retirer Layout= de la vue

Nous ne nous sommes pas trop souciés de la ligne suivante:

@{
ViewBag.Title = @Model.Nom;
Layout = "_Layout";
}

Mais comme vu dans le niveau 1, le fichier Snowfall.Web.Mvc/Views/_ViewStart.cshtml contient déjà le Layout par défaut à utiliser pour les vues.

Snowfall.Web.Mvc/Views/_ViewStart.cshtml
@{
Layout = "_Layout";
}

La vue Index de Evenements peut donc être simplifiée de la façon suivante:

Snowfall.Web.Mvc/Views/Evenements/Index.cshtml
@model Evenement;

@{
ViewBag.Title = @Model.Nom;
}

<h2>@Model.Nom</h2>
<p>@Model.Description</p>
<ul>
<li>Date: @Model.Date.ToShortDateString()</li>
<li>Capacité: @Model.Capacite</li>
<li>Prix: @Model.Prix</li>
</ul>
info

Si jamais nous avions à utiliser plusieurs Layout différents, nous pourrions le spécifier dans la vue, mais pour l'instant cela n'est pas nécessaire.