Aller au contenu principal

2-10 Vues partielles

La vue Index est fonctionnelle, mais elle pourrait être simplifiée et mieux compartimentée.

En effet, un peu à l'image d'une composante dans Angular ou tout autre cadriciel frontend du genre, il est possible d'extraire certaines portions de vues pour en faire des vues partielles.

Les vues partielles permettent de réutiliser un même bloc de HTML pour plusieurs besoins, sans avoir à le réécrire plusieurs fois. De plus, une vue partielle permet de mieux compartimenter nos vues HTML.

Dans la vue Index, une utilisation claire des vues partielles serait pour l'affichage d'un élément de la liste.

En effet, observez la portion surlignée. Cette dernière pourrait être déplacée dans son propre fichier qui représenterait un élément de la liste.

@foreach (Evenement evenement in Model)
{
<h2>@evenement.Nom</h2>
@if (@evenement.ImagePath != null)
{
<img src="@evenement.ImagePath" />
}
<p>@evenement.Description</p>
<ul>
<li>Date: @evenement.Date.ToShortDateString()</li>

@{
var classeBold = @evenement.Capacite > 1000 ? "fw-bold" : null;
}
<li class="@classeBold">Capacité: @evenement.Capacite</li>
<li>Prix: @evenement.Prix</li>
</ul>
}

Créer une vue partielle

  1. Créez une vue partielle via clic droit sur le dossier Views/Evenements -> Add -> Razor MVC Partial View Imgur
  2. Nommez la vue _Evenement
important

La convention .NET MVC veut que les vues partielles aient comme préfixe la barre de soulignement (_).

La vue partielle est nommée _Evenement ici puisqu'on cherche à afficher un événement.

Un effet de cette nomenclature est que les vues partielles se retrouvent au sommet du dossier, les isolant plus facilement des autres vues.

Imgur

Modifier la vue partielle

Le contenu par défaut de la vue est assez simple:

Snowfall.Web.Mvc/Views/Evenements/_Evenement.cshtml
@model TModel

Les mêmes principes s'appliquent par rapport à une vue normale. La vue partielle peut elle aussi recevoir un modèle (objet).

Nous savons que la vue partielle _Evenement est responsable d'afficher un événement de la liste et donc un objet de type Evenement.

  1. Modifiez donc la vue partielle pour ceci:

    Snowfall.Web.Mvc/Views/Evenements/_Evenement.cshtml
    @model Evenement
  2. Ensuite, coupez-coller le code propre à un événement de la liste à partir de la vue Index dans la vue partielle.

    Snowfall.Web.Mvc/Views/Evenements/_Evenement.cshtml
    @model Evenement

    <h2>@evenement.Nom</h2>
    @if (@evenement.ImagePath != null)
    {
    <img src="@evenement.ImagePath" />
    }
    <p>@evenement.Description</p>
    <ul>
    <li>Date: @evenement.Date.ToShortDateString()</li>

    @{
    var classeBold = @evenement.Capacite > 1000 ? "fw-bold" : null;
    }
    <li class="@classeBold">Capacité: @evenement.Capacite</li>
    <li>Prix: @evenement.Prix</li>
    </ul>

Nous avons avancé d'une étape, mais la vue partielle présentera beaucoup de code en rouge. En effet, elle ne connait pas la variable @evenement!

Par contre, elle connait la variable @Model! Variable qui fait référence à un événement normalement.

Vous pouvez ainsi modifier et remplacer les références à @evenement par @Model.

astuce

Vous pouvez faire un clic doit sur la variable @evenement et ensuite choisir Refactor -> Rename.

Snowfall.Web.Mvc/Views/Evenements/_Evenement.cshtml
@model Evenement

<h2>@Model.Nom</h2>
@if (@Model.ImagePath != null)
{
<img src="@Model.ImagePath" />
}
<p>@Model.Description</p>
<ul>
<li>Date: @Model.Date.ToShortDateString()</li>

@{
var classeBold = @Model.Capacite > 1000 ? "fw-bold" : null;
}
<li class="@classeBold">Capacité: @Model.Capacite</li>
<li>Prix: @Model.Prix</li>
</ul>

Faire le lien entre la vue et la vue partielle via <partial>

La vue principale (Index) est maintenant réduite à ceci:

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

@{
ViewBag.Title = "Événements";
}

<h1>Événements</h1>

@foreach (Evenement evenement in Model)
{

}

Pour faire référence à la vue partielle, on peut utiliser une balise spéciale, propre à .NET MVC, soit la balise <partial>.

La balise prend en argument le nom de la vue partielle (name) et optionnellement, un modèle (objet).

Rider est très efficace dans son autocomplétion pour vous aider à choisir la bonne vue:

Imgur

Ainsi, la vue Index devient:

Snowfall.Web.Mvc/Views/Evenements/Index.cshtml
@foreach (Evenement evenement in Model)
{
<partial name="_Evenement" />
}

Par contre, si vous essayez de rouler l'application, vous obtiendrez l'erreur suivante:

An unhandled exception occurred while processing the request.
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Collections.Generic.List`1[Snowfall.Web.Mvc.Models.Evenement]', but this ViewDataDictionary instance requires a model item of type 'Snowfall.Web.Mvc.Models.Evenement'.
important

Le comportement par défaut en utilisant <partial> est que le modèle de la vue parente sera passé automatiquement à la vue partielle.

Or, dans notre cas, la vue parente détient une liste d'événements et la vue partielle s'attend à recevoir un seul événement.

On doit donc passer la variable locale de la boucle, soit la variable evenement.

Pour ce faire, on utilise le paramètre model afin de passer en argument la variable de boucle evenement:

Snowfall.Web.Mvc/Views/Evenements/Index.cshtml
@foreach (Evenement evenement in Model)
{
<partial name="_Evenement" model="evenement"/>
}

Si vous essayez dans le navigateur, le tout devrait à nouveau fonctionner! 🎉

Imgur