Механизм просмотра Razor - как добавить частичные представления

84

Мне было интересно, если это возможно, лучший способ визуализировать партиал с использованием нового движка Razor View. Я понимаю, что к тому времени это еще не было закончено полностью

Прямо сейчас я использую RenderPage для визуализации пользовательского элемента управления:

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

Страница, вызывающая RenderPage, использует страницу макета (главную) с тремя определенными разделами: TitleContent, HeadContent и Maincontent. Когда я пытаюсь отобразить свой элемент управления локалью с этой страницы, кажется, что эти разделы также необходимы - они должны быть обязательными только на вызывающей странице и присутствуют. Я получаю следующее сообщение, независимо от того, включаю ли я разделы в свое частичное представление (очевидно, я не хочу включать эти разделы, но это показалось мне интересным моментом для отладки ...).

Следующие разделы были определены, но не отображены на странице макета '~ / Views / Shared / LocaleUserControl.cshtml': TitleContent; HeadContent; Основное содержание

Мое частичное мнение следующее (адаптировано из следующей ссылки ):

@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.
источник

Ответы:

125

Ваш партиал очень похож на шаблон редактора, поэтому вы можете включить его как таковой (конечно, при условии, что ваш партиал помещен во ~/views/controllername/EditorTemplatesвложенную папку):

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

Или, если это не так, просто:

@Html.Partial("nameOfPartial", Model)
Дарин Димитров
источник
Спасибо за обратную связь ... Html.EditorFor может быть хорошей идеей в этом случае - но мне было бы интересно увидеть альтернативы, поскольку это не относится к более сложным примерам - я обязательно столкнусь с этим снова в ближайшее время. Html.Partial не будет работать, так как он должен быть производным от ViewPage или ViewUserControl, тогда как фрагмент бритвы является производным от WebViewPage ...
JP.
4
Html.Partial отлично работает. Запустите новый проект ASP.NET MVC 3 в Visual Studio с помощью механизма просмотра Razor, откройте _Layout.cshtml файл в Sharedпапке и проверьте, как выполняется включение того, от _LogOnPartial.cshtmlчего происходит WebViewPage(с помощью Html.Partial). Так что нет, частичное не должно производиться ViewPageили ViewUserControlвообще Html.Partialработать.
Дарин Димитров
1
Хммм, похоже, вы правы. Также похоже, что мне нужно кое-что отладить. Благодаря!
JP.
1
Раньше я использовал Html.RenderPartialстраницу ASPX, которая возвращает void. Html.Partialвозвращает MvcHtmlString. Итак, если ваш партиал содержит много разметки, вы создадите потенциально очень большой строковый объект только для его немедленной сборки. Есть ли подход, поддерживающий рендеринг непосредственно на выходе с помощью Razor?
Дрю Ноукс
2
@Draw Я думаю, что упаковка RenderPartial в @{...}блок должна работать. Не знаю, есть ли лучшее решение.
CodesInChaos 02
0

Если вы не хотите дублировать код и, как и я, вы просто хотите отображать статистику, в своей модели представления вы можете просто передать модели, из которых вы хотите получать данные, вот так:

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

Затем в вашем контроллере просто выполните запросы к соответствующим моделям, передайте их модели представления и верните ее, например:

GameViewModel PlayerStats = new GameViewModel();

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

[код для проверки результатов]

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

Как я уже сказал, вам следует делать это только в том случае, если вы хотите отображать статистику из соответствующих таблиц, и никакой другой части процесса CRUD не происходит из соображений безопасности, упомянутых выше другими людьми.

Джей
источник