Mam witrynę MVC3 używającą Razor jako silnika widoku. Chcę, aby moja witryna umożliwiała skórowanie. Większość możliwych skórek jest na tyle podobnych, że mogą pochodzić ze wspólnego układu głównego.
Dlatego rozważam ten projekt:
Chciałbym jednak mieć możliwość wywołania RenderSection
dolnej warstwy _Common.cshtml
i renderowania sekcji zdefiniowanej w górnej warstwie Detail.cshtml
. To nie działa: RenderSection
najwyraźniej renderuje tylko sekcje zdefiniowane w następnej warstwie.
Oczywiście mogę zdefiniować każdą sekcję w każdej skórce. Na przykład, jeśli _Common
trzeba wywołać RenderSection("hd")
sekcję zdefiniowaną w Detail
, po prostu umieszczam to w każdej _Skin
i działa:
@section hd {
@RenderSection("hd")
}
Powoduje to pewne zduplikowanie kodu (ponieważ każda skórka musi teraz mieć tę samą sekcję) i generalnie sprawia wrażenie bałaganu. Wciąż jestem nowy w Razor i wygląda na to, że brakuje mi czegoś oczywistego.
Podczas debugowania widzę pełną listę zdefiniowanych sekcji w WebViewPage.SectionWritersStack. Gdybym mógł po prostu powiedzieć RenderSection, aby przejrzał całą listę przed rezygnacją, znalazłby sekcję, której potrzebuję. Niestety, sekcja SectionWritersStack jest niepubliczna.
Alternatywnie, gdybym mógł uzyskać dostęp do hierarchii stron układu i spróbować wykonać RenderSection w każdym innym kontekście, mógłbym zlokalizować potrzebną sekcję. Prawdopodobnie czegoś mi brakuje, ale nie widzę żadnego sposobu, aby to zrobić.
Czy istnieje sposób na osiągnięcie tego celu inny niż metoda, którą już opisałem?
źródło
@helper ForwardSection( string section ) { if (IsSectionDefined(section)) { DefineSection(section, () => Write(RenderSection(section))); } }
Czy to zadziała?
źródło
Nie jestem pewien, czy jest to możliwe w MVC 3, ale w MVC 5 jestem w stanie to pomyślnie zrobić, używając następującej sztuczki:
W
~/Views/Shared/_Common.cshtml
napisać swój wspólny kod HTML, takich jak:<!DOCTYPE html> <html lang="fa"> <head> <title>Skinnable - @ViewBag.Title</title> </head> <body> @RenderBody() </body> </html>
W
~/Views/_ViewStart.cshtml
:@{ Layout = "~/Views/Shared/_Common.cshtml"; }
Teraz wszystko, co musisz zrobić, to użyć
_Common.cshtml
jakoLayout
dla wszystkich skórek. Na przykład w~/Views/Shared/Skin1.cshtml
:@{ Layout = "~/Views/Shared/_Common.cshtml"; } <p>Something specific to Skin1</p> @RenderBody()
Teraz możesz ustawić skórkę jako układ w kontrolerze lub widoku na podstawie swoich kryteriów. Na przykład:
public ActionResult Index() { //.... if (user.SelectedSkin == Skins.Skin1) return View("ViewName", "Skin1", model); }
Jeśli uruchomisz powyższy kod, powinieneś otrzymać stronę HTML z zawartością
Skin1.cshtml
i_Common.cshtml
Krótko mówiąc, ustawisz układ strony układu (skóry).
źródło
Nie jestem pewien, czy to ci pomoże, ale napisałem kilka metod rozszerzających, aby pomóc w „uwypuklaniu” sekcji z części podrzędnych, co powinno działać również dla układów zagnieżdżonych.
Wstrzykiwanie zawartości do określonych sekcji z częściowego widoku ASP.NET MVC 3 z silnikiem Razor View
Zadeklaruj w układzie potomnym / widoku / częściowym
Renderuj w dowolnym rodzicu
Zobacz link do odpowiedzi, aby uzyskać więcej przypadków użycia, takich jak renderowanie tylko jednego opóźnionego bloku, nawet jeśli został zadeklarowany w widoku powtarzalnym, renderowanie określonych opóźnionych bloków itp.
źródło