Moteur de vue Razor - Comment puis-je ajouter des vues partielles

84

Je me demandais quelle était, si cela est possible, la meilleure façon de rendre un partiel en utilisant le nouveau moteur de vue rasoir. Je comprends que c'est quelque chose qui n'était pas complètement terminé à l'époque

En ce moment, j'utilise RenderPage pour rendre le contrôle utilisateur:

@RenderPage("~/Views/Shared/LocaleUserControl.cshtml",ViewData.Model)

La page appelant RenderPage utilise une page de mise en page (maître) avec trois sections définies: TitleContent, HeadContent et Maincontent. Lorsque j'essaye de rendre mon contrôle des paramètres régionaux à partir de cette page, il semble que ces sections sont également requises - elles ne devraient être requises que dans la page d'appel et sont présentes. Je reçois le message suivant, que j'inclue ou non les sections dans ma vue partielle (évidemment je ne veux pas inclure ces sections mais cela m'a semblé être un point de débogage intéressant ...).

Les sections suivantes ont été définies mais n'ont pas été rendues sur la page de mise en page '~ / Views / Shared / LocaleUserControl.cshtml': TitleContent; HeadContent; Contenu principal

Ma vue partielle est la suivante (adaptée du lien suivant ):

@inherits System.Web.Mvc.WebViewPage<LocaleBaseModel>
@using System.Web.UI;

<p>
     @Html.LabelFor(model => Model.CountryName)
    <br />
    @Html.DropDownListFor(model => Model.CountryName,null, string.Empty, new { @class = "text", accesskey="u"})
</p>
<p>
     @Html.LabelFor(model => Model.StateProvince)
    <br />
     @Html.DropDownListFor(model => Model.StateProvince, null, string.Empty, new { @class = "text", accesskey="t" })
</p>


<script type="text/javascript">
    $(function () {
        var countries = $("#CountryName");
        var statesprovinces = $("#StateProvince");
        countries.change(function () {
            statesprovinces.find('option').remove();
            var url = '@Url.Action("GetStatesProvinces", "Base")';
            $.getJSON(url, { countryId: countries.val() }, function (data) {
                $(data).each(function () {
                    $("<option value=" + this.ID + ">" + this.Name + "</option>").appendTo(statesprovinces);
                });
            });
        });
    });
</script>
JP.
la source

Réponses:

124

Votre partiel ressemble beaucoup à un modèle d'éditeur, vous pouvez donc l'inclure en tant que tel (en supposant bien sûr que votre partiel est placé dans le ~/views/controllername/EditorTemplatessous - dossier):

@Html.EditorFor(model => model.SomePropertyOfTypeLocaleBaseModel)

Ou si ce n'est pas le cas simplement:

@Html.Partial("nameOfPartial", Model)
Darin Dimitrov
la source
Merci pour les commentaires ... Html.EditorFor peut être une bonne idée dans ce cas - mais je serais intéressé de voir des alternatives car ce n'est pas le cas pour des exemples plus complexes - je vais certainement le revoir bientôt. Html.Partial ne fonctionnera pas car il doit dériver de ViewPage ou ViewUserControl alors que le rasoir partiel dérive de WebViewPage ...
JP.
4
Html.Partial fonctionne parfaitement bien. Démarrez un nouveau projet ASP.NET MVC 3 dans Visual Studio à l'aide du moteur de vue Razor, ouvrez le _Layout.cshtml fichier dans le Shareddossier et vérifiez comment l'inclusion _LogOnPartial.cshtmldont dérive WebViewPageest effectuée (à l'aide de Html.Partial). Donc non, le partiel n'a pas besoin de dériver ViewPageou pas ViewUserControldu tout pour Html.Partialfonctionner.
Darin Dimitrov
1
Hmmm, on dirait que vous avez raison. Il semble également que j'ai du débogage à faire. Merci!
JP.
1
J'avais l'habitude d'utiliser Html.RenderPartialavec la page ASPX, qui retourne void. Html.Partialrenvoie un MvcHtmlString. Donc, si votre partiel contient beaucoup de balisage, vous allez créer un objet chaîne potentiellement très volumineux uniquement pour le GC immédiatement. Existe-t-il une approche qui prend en charge le rendu directement sur la sortie à l'aide de Razor?
Drew Noakes le
2
@Draw Je pense que l'intégration de RenderPartial dans un @{...}bloc devrait fonctionner. Aucune idée s'il existe une meilleure solution.
CodesInChaos
0

Si vous ne voulez pas dupliquer le code, et comme moi, vous voulez juste afficher des statistiques, dans votre modèle de vue, vous pouvez simplement passer les modèles dont vous souhaitez obtenir des données comme suit:

public class GameViewModel
{
    public virtual Ship Ship { get; set; }
    public virtual GamePlayer GamePlayer { get; set; }     
}

Ensuite, dans votre contrôleur, exécutez simplement vos requêtes sur les modèles respectifs, transmettez-les au modèle de vue et renvoyez-le, exemple:

GameViewModel PlayerStats = new GameViewModel();

GamePlayer currentPlayer = (from c in db.GamePlayer [more queries]).FirstOrDefault();

[code pour vérifier si les résultats]

//pass current player into custom view model
PlayerStats.GamePlayer = currentPlayer;

Comme je l'ai dit, vous ne devriez vraiment le faire que si vous souhaitez afficher les statistiques des tables pertinentes, et qu'aucune autre partie du processus CRUD n'est en cours, pour des raisons de sécurité que d'autres personnes ont mentionnées ci-dessus.

Geai
la source