Réutiliser l’interface utilisateur avec des pages maîtres et des vues partielles
par Microsoft
Il s’agit de l’étape 7 d’un didacticiel gratuit sur l’application « NerdDinner » qui explique comment créer une petite application web, mais complète, à l’aide de ASP.NET MVC 1.
L’étape 7 examine les façons dont nous pouvons appliquer le « principe DRY » dans nos modèles d’affichage pour éliminer la duplication de code, à l’aide de modèles d’affichage partiel et de pages master.
Si vous utilisez ASP.NET MVC 3, nous vous recommandons de suivre les didacticiels Prise en main Avec MVC 3 ou MVC Music Store.
NerdDinner Step 7: Partials and Master Pages
L’une des philosophies de conception ASP.NET MVC adopte est le principe « Ne pas vous répéter » (communément appelé « DRY »). Une conception DRY permet d’éliminer la duplication du code et de la logique, ce qui rend les applications plus rapides à générer et à gérer.
Nous avons déjà vu le principe DRY appliqué dans plusieurs de nos scénarios NerdDinner. Voici quelques exemples : notre logique de validation est implémentée dans notre couche de modèle, ce qui permet de l’appliquer à la fois dans les scénarios de modification et de création dans notre contrôleur ; nous réutilisant le modèle d’affichage « NotFound » dans les méthodes d’action Modifier, Détails et Supprimer ; nous utilisons un modèle de nommage de convention avec nos modèles d’affichage, ce qui élimine la nécessité de spécifier explicitement le nom lorsque nous appelons la méthode d’assistance View() ; et nous réutilisent la classe DinnerFormViewModel pour les scénarios d’action Modifier et Créer.
Voyons maintenant comment appliquer le « principe DRY » dans nos modèles d’affichage pour éliminer la duplication de code.
Réinitialisation de nos modèles d’affichage modifier et créer des modèles d’affichage
Actuellement, nous utilisons deux modèles d’affichage différents : « Edit.aspx » et « Create.aspx » pour afficher l’interface utilisateur de notre formulaire dîner. Une comparaison visuelle rapide de celles-ci met en évidence leur similitude. Voici à quoi ressemble le formulaire de création :
Et voici à quoi ressemble notre formulaire « Modifier » :
Il n’y a pas beaucoup de différence ? Outre le titre et le texte d’en-tête, la disposition du formulaire et les contrôles d’entrée sont identiques.
Si nous ouvrons les modèles d’affichage « Edit.aspx » et « Create.aspx », nous constatons qu’ils contiennent une disposition de formulaire et un code de contrôle d’entrée identiques. Cette duplication signifie que nous finissent par avoir à apporter des modifications deux fois chaque fois que nous introduisons ou changeons une nouvelle propriété dinner - ce qui n’est pas bon.
Utilisation de modèles d’affichage partiel
ASP.NET MVC prend en charge la possibilité de définir des modèles de « vue partielle » qui peuvent être utilisés pour encapsuler la logique de rendu d’une vue pour une sous-partie d’une page. Les « éléments partiels » fournissent un moyen utile de définir une logique de rendu d’affichage une seule fois, puis de la réutiliser à plusieurs endroits dans une application.
Pour faciliter la duplication de nos modèles d’affichage Edit.aspx et Create.aspx, nous pouvons créer un modèle d’affichage partiel nommé « DinnerForm.ascx » qui encapsule la disposition du formulaire et les éléments d’entrée communs aux deux. Pour ce faire, cliquez avec le bouton droit sur notre répertoire /Views/Dinners et choisissez la commande de menu « Add-View> » :
La boîte de dialogue « Ajouter une vue » s’affiche. Nous allons nommer la nouvelle vue que nous voulons créer « DinnerForm », cocher la case « Créer une vue partielle » dans la boîte de dialogue et indiquer que nous allons lui passer une classe DinnerFormViewModel :
Lorsque nous cliquons sur le bouton « Ajouter », Visual Studio crée un modèle d’affichage « DinnerForm.ascx » pour nous dans le répertoire « \Views\Dinners ».
Nous pouvons ensuite copier/coller le code de disposition de formulaire/de contrôle d’entrée en double à partir de nos modèles d’affichage Edit.aspx/Create.aspx dans notre nouveau modèle d’affichage partiel « DinnerForm.ascx » :
<%= Html.ValidationSummary("Please correct the errors and try again.") %>
<% using (Html.BeginForm()) { %>
<fieldset>
<p>
<label for="Title">Dinner Title:</label>
<%= Html.TextBox("Title", Model.Dinner.Title) %>
<%=Html.ValidationMessage("Title", "*") %>
</p>
<p>
<label for="EventDate">Event Date:</label>
<%= Html.TextBox("EventDate", Model.Dinner.EventDate) %>
<%= Html.ValidationMessage("EventDate", "*") %>
</p>
<p>
<label for="Description">Description:</label>
<%= Html.TextArea("Description", Model.Dinner.Description) %>
<%= Html.ValidationMessage("Description", "*") %>
</p>
<p>
<label for="Address">Address:</label>
<%= Html.TextBox("Address", Model.Dinner.Address) %>
<%= Html.ValidationMessage("Address", "*") %>
</p>
<p>
<label for="Country">Country:</label>
<%= Html.DropDownList("Country", Model.Countries) %>
<%= Html.ValidationMessage("Country", "*") %>
</p>
<p>
<label for="ContactPhone">Contact Phone #:</label>
<%= Html.TextBox("ContactPhone", Model.Dinner.ContactPhone) %>
<%= Html.ValidationMessage("ContactPhone", "*") %>
</p>
<p>
<input type="submit" value="Save"/>
</p>
</fieldset>
<% } %>
Nous pouvons ensuite mettre à jour nos modèles d’affichage Modifier et Créer pour appeler le modèle partiel DinnerForm et éliminer la duplication de formulaire. Pour ce faire, nous pouvons appeler Html.RenderPartial(« DinnerForm ») dans nos modèles d’affichage :
Create.aspx
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
Host a Dinner
</asp:Content>
<asp:Content ID="Create" ContentPlaceHolderID="MainContent" runat="server">
<h2>Host a Dinner</h2>
<% Html.RenderPartial("DinnerForm"); %>
</asp:Content>
Edit.aspx
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
Edit: <%=Html.Encode(Model.Dinner.Title) %>
</asp:Content>
<asp:Content ID="Edit" ContentPlaceHolderID="MainContent" runat="server">
<h2>Edit Dinner</h2>
<% Html.RenderPartial("DinnerForm"); %>
</asp:Content>
Vous pouvez qualifier explicitement le chemin d’accès du modèle partiel souhaité lors de l’appel de Html.RenderPartial (par exemple : ~Views/DinnerForm.ascx). Toutefois, dans notre code ci-dessus, nous profitons du modèle de nommage basé sur la convention dans ASP.NET MVC et nous spécifions simplement « DinnerForm » comme nom de la partie à restituer. Lorsque nous procédons ainsi ASP.NET MVC s’affiche d’abord dans le répertoire des vues basées sur la convention (pour DinnersController, il s’agit de /Views/Dinners). S’il ne trouve pas le modèle partiel, il le recherche dans le répertoire /Views/Shared.
Lorsque Html.RenderPartial() est appelé avec uniquement le nom de la vue partielle, ASP.NET MVC transmet à la vue partielle les mêmes objets de dictionnaire Model et ViewData que ceux utilisés par le modèle d’affichage appelant. Il existe également des versions surchargées de Html.RenderPartial() qui vous permettent de passer un autre objet Model et/ou un dictionnaire ViewData pour l’affichage partiel à utiliser. Cela est utile pour les scénarios où vous souhaitez uniquement passer un sous-ensemble du Modèle/ViewModel complet.
Rubrique latérale : Pourquoi <% %> au lieu de <%= %>? |
---|
L’une des choses subtiles que vous avez peut-être remarquées avec le code ci-dessus est que nous utilisons un <bloc %> au lieu d’un <bloc %= %> lors de l’appel de Html.RenderPartial(). <%= %> de blocs dans ASP.NET indiquent qu’un développeur souhaite afficher une valeur spécifiée (par exemple : <%= « Hello » %> affiche « Hello »). <% les blocs %> indiquent plutôt que le développeur souhaite exécuter du code et que toute sortie rendue dans ces blocs doit être effectuée explicitement (par exemple : <% Response.Write(« Hello ») %>. La raison pour laquelle nous utilisons un <bloc %> avec notre code Html.RenderPartial ci-dessus est que la méthode Html.RenderPartial() ne retourne pas de chaîne et génère le contenu directement dans le flux de sortie du modèle d’affichage appelant. Elle le fait pour des raisons d’efficacité des performances, ce qui évite d’avoir à créer un objet de chaîne temporaire (potentiellement très volumineux). Cela réduit l’utilisation de la mémoire et améliore le débit global de l’application. Une erreur courante lors de l’utilisation de Html.RenderPartial() consiste à oublier d’ajouter un point-virgule à la fin de l’appel lorsqu’il se trouve dans un <bloc % .> Par exemple, ce code provoque une erreur du compilateur : <% Html.RenderPartial(« DinnerForm ») %> Vous devez plutôt écrire : <% Html.RenderPartial(« DinnerForm »); %> Cela est dû au fait que <% %> blocs sont des instructions de code autonomes et que, lors de l’utilisation d’instructions de code C#, vous devez se terminer par un point-virgule. |
Utilisation de modèles d’affichage partiel pour clarifier le code
Nous avons créé le modèle de vue partielle « DinnerForm » pour éviter de dupliquer la logique de rendu d’affichage à plusieurs endroits. Il s’agit de la raison la plus courante pour créer des modèles d’affichage partiel.
Parfois, il est toujours judicieux de créer des vues partielles même quand elles ne sont appelées qu’à un seul endroit. Les modèles d’affichage très compliqués peuvent souvent devenir beaucoup plus faciles à lire lorsque leur logique de rendu d’affichage est extraite et partitionnée dans un ou plusieurs modèles partiels bien nommés.
Par exemple, considérez l’extrait de code ci-dessous du site. master fichier dans notre projet (que nous examinerons bientôt). Le code est relativement simple à lire, en partie parce que la logique d’affichage d’un lien de connexion/déconnexion en haut à droite de l’écran est encapsulée dans la partie « LogOnUserControl » :
<div id="header">
<div id="title">
<h1>My MVC Application</h1>
</div>
<div id="logindisplay">
<% Html.RenderPartial("LogOnUserControl"); %>
</div>
<div id="menucontainer">
<ul id="menu">
<li><%=Html.ActionLink("Home", "Index", "Home")%></li>
<li><%=Html.ActionLink("About", "About", "Home")%></li>
</ul>
</div>
</div>
Chaque fois que vous vous trouvez confus en essayant de comprendre le balisage html/code dans un modèle d’affichage, déterminez s’il ne serait pas plus clair si une partie de celui-ci était extraite et refactorisée dans des vues partielles bien nommées.
Pages maîtres
En plus de prendre en charge les vues partielles, ASP.NET MVC prend également en charge la possibilité de créer des modèles « master page » qui peuvent être utilisés pour définir la disposition commune et le code HTML de niveau supérieur d’un site. Les contrôles d’espace réservé de contenu peuvent ensuite être ajoutés à la page master pour identifier les régions remplaçables qui peuvent être remplacées ou « remplies » par des affichages. Cela fournit un moyen très efficace (et DRY) d’appliquer une disposition commune à une application.
Par défaut, un modèle de page master est automatiquement ajouté aux nouveaux projets ASP.NET MVC. Cette page master est nommée « Site.master » et se trouve dans le dossier \Views\Shared\ :
Site par défaut. master fichier ressemble à celui ci-dessous. Il définit le code HTML externe du site, ainsi qu’un menu pour la navigation en haut. Il contient deux contrôles d’espace réservé de contenu remplaçables : l’un pour le titre et l’autre pour l’emplacement où le contenu principal d’une page doit être remplacé :
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>
<asp:ContentPlaceHolder ID="TitleContent" runat="server" />
</title>
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="page">
<div id="header">
<div id="title">
<h1>My MVC Application</h1>
</div>
<div id="logindisplay">
<% Html.RenderPartial("LogOnUserControl"); %>
</div>
<div id="menucontainer">
<ul id="menu">
<li><%=Html.ActionLink("Home", "Index", "Home")%></li>
<li><%=Html.ActionLink("About", "About", "Home")%></li>
</ul>
</div>
</div>
<div id="main">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
</div>
</div>
</body>
</html>
Tous les modèles d’affichage que nous avons créés pour notre application NerdDinner (« List », « Details », « Edit », « Create », « NotFound », etc.) sont basés sur ce Site. master modèle. Cela est indiqué via l’attribut « MasterPageFile » qui a été ajouté par défaut à la <directive % top % @ Page %> lorsque nous avons créé nos vues à l’aide de la boîte de dialogue « Ajouter une vue » :
<%@ Page Inherits="System.Web.Mvc.ViewPage<NerdDinner.Controllers.DinnerViewModel>" MasterPageFile="~/Views/Shared/Site.Master" %>
Cela signifie que nous pouvons modifier le site. master contenu et faire en sorte que les modifications soient appliquées et utilisées automatiquement lorsque nous affichons l’un de nos modèles d’affichage.
Nous allons mettre à jour notre site. section d’en-tête de master afin que l’en-tête de notre application soit « NerdDinner » au lieu de « Mon application MVC ». Nous allons également mettre à jour notre menu de navigation afin que le premier onglet soit « Find a Dinner » (géré par la méthode d’action Index() de HomeController), et nous allons ajouter un nouvel onglet appelé « Host a Dinner » (géré par la méthode d’action Create() de DinnersController) ) :
<div id="header">
<div id="title">
<h1>NerdDinner</h1>
</div>
<div id="logindisplay">
<% Html.RenderPartial("LoginStatus"); %>
</div>
<div id="menucontainer">
<ul id="menu">
<li><%=Html.ActionLink("Find Dinner", "Index", "Home")%></li>
<li><%=Html.ActionLink("Host Dinner", "Create", "Dinners")%></li>
<li><%=Html.ActionLink("About", "About", "Home")%></li>
</ul>
</div>
</div>
Lorsque nous enregistrons le site. master fichier et actualisez notre navigateur, nos modifications d’en-tête s’affichent dans toutes les vues de notre application. Par exemple :
Et avec l’URL /Dinners/Edit/[id] :
étape suivante
Les pages partielles et master offrent des options très flexibles qui vous permettent d’organiser correctement les vues. Vous constaterez qu’ils vous aident à éviter de dupliquer le contenu/le code de l’affichage et à faciliter la lecture et la maintenance de vos modèles d’affichage.
Revenons maintenant au scénario de référencement que nous avons créé précédemment et activez la prise en charge de la pagination évolutive.