Silnik widoku Razor - jak mogę dodać częściowe widoki

84

Zastanawiałem się, co, jeśli to możliwe, jest najlepszym sposobem renderowania częściowego za pomocą nowego silnika widoku brzytwy. Rozumiem, że jest to coś, co nie było do końca ukończone

W tej chwili używam RenderPage do renderowania kontrolki użytkownika:

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

Strona wywołująca RenderPage używa strony układu (wzorcowej) z trzema zdefiniowanymi sekcjami: TitleContent, HeadContent i Maincontent. Kiedy próbuję wyrenderować kontrolę ustawień regionalnych z tej strony, wydaje się, że te sekcje są również wymagane - powinny być wymagane tylko na stronie wywołującej i są obecne. Otrzymuję następujący komunikat, niezależnie od tego, czy uwzględnię sekcje w moim częściowym widoku (oczywiście nie chcę uwzględniać tych sekcji, ale wydawało się to interesującym punktem debugowania ...).

Następujące sekcje zostały zdefiniowane, ale nie zostały wyrenderowane na stronie układu „~ / Views / Shared / LocaleUserControl.cshtml”: TitleContent; HeadContent; Główna zawartość

Mój częściowy pogląd jest następujący (na podstawie poniższego linku ):

@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.
źródło

Odpowiedzi:

125

Częściowo wygląda jak szablon edytora, więc możesz go dołączyć jako taki (zakładając oczywiście, że część jest umieszczona w ~/views/controllername/EditorTemplatespodfolderze):

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

A jeśli tak nie jest, po prostu:

@Html.Partial("nameOfPartial", Model)
Darin Dimitrov
źródło
Dzięki za informację zwrotną ... Html.EditorFor może być dobrym pomysłem w tym przypadku - ale chciałbym zobaczyć alternatywy, ponieważ tak nie jest w przypadku bardziej złożonych przykładów - na pewno wkrótce znów się z tym spotkam. Html.Partial nie będzie działać, ponieważ musi pochodzić z ViewPage lub ViewUserControl, podczas gdy część Razor pochodzi z WebViewPage ...
JP.
4
Html.Partial działa doskonale. Uruchom nowy projekt ASP.NET MVC 3 w programie Visual Studio przy użyciu aparatu widoku Razor, otwórz _Layout.cshtml plik w Sharedfolderze i sprawdź, jak odbywa się włączenie, z _LogOnPartial.cshtmlktórego pochodzi WebViewPage(przy użyciu Html.Partial). Więc nie, częściowe nie muszą pochodzić ViewPageani ViewUserControlw ogóle, Html.Partialaby działać.
Darin Dimitrov
1
Hmmm, wygląda na to, że masz rację. Wygląda też na to, że muszę zrobić debugowanie. Dzięki!
JP.
1
Kiedyś używałem Html.RenderPartialze stroną ASPX, która zwraca void. Html.Partialzwraca plik MvcHtmlString. Tak więc, jeśli twoja część zawiera dużo znaczników, utworzysz potencjalnie bardzo duży obiekt łańcuchowy tylko do natychmiastowego GC. Czy istnieje podejście, które obsługuje renderowanie bezpośrednio do danych wyjściowych przy użyciu Razor?
Drew Noakes
2
@Draw Myślę, że zawijanie RenderPartial do @{...}bloku powinno działać. Nie mam pojęcia, czy istnieje lepsze rozwiązanie.
CodesInChaos
0

Jeśli nie chcesz powielać kodu i tak jak ja chcesz po prostu pokazać statystyki, w modelu widoku możesz po prostu przekazać modele, z których chcesz uzyskać dane, w następujący sposób:

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

Następnie w kontrolerze po prostu uruchom zapytania na odpowiednich modelach, przekaż je do modelu widoku i zwróć je, przykład:

GameViewModel PlayerStats = new GameViewModel();

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

[kod do sprawdzenia wyników]

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

Tak jak powiedziałem, powinieneś to zrobić naprawdę tylko wtedy, gdy chcesz wyświetlić statystyki z odpowiednich tabel, a żadna inna część procesu CRUD nie ma miejsca, ze względów bezpieczeństwa, o których inni wspominali powyżej.

Sójka
źródło