剃刀嵌套布局与级联部分
我有一个使用Razor作为视图引擎的MVC3网站。 我希望我的网站可以换肤。 大多数可能的皮肤足够相似,可以从共享的主布局派生。
所以我正在考虑这个devise:
但是,我希望能够调用底层的RenderSection
中的_Common.cshtml
,并使其在最上层的Detail.cshtml
定义一个部分。 这不起作用: RenderSection
显然只渲染定义下一层的部分。
当然,我可以在每个皮肤中定义每个部分。 例如,如果_Common
需要为Detail
定义的部分调用RenderSection("hd")
,我只需将它放在每个_Skin
,它就可以工作:
@section hd { @RenderSection("hd") }
这会导致代码的重复(因为每个皮肤现在都必须具有相同的部分)并且通常感觉混乱。 我对Razor还是个新手,似乎我可能会错过一些明显的东西。
debugging时,我可以在WebViewPage.SectionWritersStack中看到完整的定义部分列表。 如果我能告诉RenderSection在放弃之前查看整个列表,它会find我需要的部分。 唉,SectionWritersStack是非公开的。
或者,如果我可以访问布局页面的层次结构,并尝试在每个不同的上下文中执行RenderSection,我可以find我需要的部分。 我可能错过了一些东西,但我没有看到任何方式来做到这一点。
除了我已经提到的方法之外,有什么方法可以实现这个目标吗?
这实际上是不可能的今天使用公共API(除了使用部分重新定义方法)。 使用私人reflection可能会有一些运气,但这当然是一个脆弱的方法。 我们将考虑在下一个Razor版本中使这个场景更容易。
与此同时,这里有几篇关于这个主题的博文:
@helper ForwardSection( string section ) { if (IsSectionDefined(section)) { DefineSection(section, () => Write(RenderSection(section))); } }
这会做这个工作吗?
我不知道如果这是可能的MVC 3,但在MVC 5我能够成功地做到这一点使用以下技巧:
在~/Views/Shared/_Common.cshtml
写下你常见的HTML代码:
<!DOCTYPE html> <html lang="fa"> <head> <title>Skinnable - @ViewBag.Title</title> </head> <body> @RenderBody() </body> </html>
在~/Views/_ViewStart.cshtml
:
@{ Layout = "~/Views/Shared/_Common.cshtml"; }
现在你所要做的就是使用_Common.cshtml
作为所有皮肤的Layout
。 例如,在~/Views/Shared/Skin1.cshtml
:
@{ Layout = "~/Views/Shared/_Common.cshtml"; } <p>Something specific to Skin1</p> @RenderBody()
现在,您可以根据您的标准将外观设置为控制器或视图中的布局。 例如:
public ActionResult Index() { //.... if (user.SelectedSkin == Skins.Skin1) return View("ViewName", "Skin1", model); }
如果你运行上面的代码,你应该得到一个包含Skin1.cshtml
和_Common.cshtml
内容的HTML页面
总之,您将设置(皮肤)布局页面的布局。
不知道这是否会对你有所帮助,但是我写了一些扩展方法来帮助从部分内部“冒泡”部分,这也适用于嵌套布局。
使用Razor View Engine从ASP.NET MVC 3的局部视图中将内容注入特定的部分
在子布局/视图/部分声明
@using (Html.Delayed()) { <b>show me multiple times, @Model.Whatever</b> }
在任何父母中呈现
@Html.RenderDelayed();
查看更多用例的答案链接,例如即使在重复视图中声明,渲染一个延迟块,渲染特定的延迟块等,也是如此。
- MVC,EF – DataContext单例实例Per-Web-Request在Unity中
- 活动菜单项 – asp.net mvc3母版页
- 来自默认(EditorTemplates / DisplayTemplates)以外的文件夹的MVC模板?
- ASP.NET MVC – 根据Active Directoryvalidation用户,但要求input用户名和密码
- 模糊引用与完全相同的命名空间
- 有什么好理由使用FormCollection而不是ViewModel?
- url内的双转义序列:请求过滤模块configuration为拒绝包含双转义序列的请求
- 将mvc3单选button绑定到模型的正确方法
- 请求redirect到/ Account / Login?ReturnUrl =%2f,因为MVC 3安装在服务器上