【问题标题】:Can partial views affect markup outside themselves?部分视图会影响自身之外的标记吗?
【发布时间】:2013-11-29 20:39:52
【问题描述】:

Razor 局部是否可以相互交流/影响布局?他们是否有可能影响外部的标记——尤其是“上方”——他们自己?

我喜欢 Webforms 中的控件的一点是,它们可以与母版页或彼此“通信”。

例如,如果用户控件需要一些特殊的 CSS,您可以这样做:

Page.Head.Controls.Add(new LiteralControl("<style>[something here]</style>"));

这会在页面的 HEAD 标记中注入一个 STYLE 块。因此,用户控件可以“在”自身“外部”对话——在这种情况下——“在”自身“之上”。即使用户控件位于页面底部,它也可以“向上”页面并影响其他控件和标记。

现在,使用 MVC,假设我有一个部分。该部分需要自定义 CSS。它如何与布局模板对话以告诉它将 CSS 放入 HEAD 标记中?另外,假设这个部分被使用了两次——你如何确保它只使用一次?

我有一个 HeadTagContent 部分(应用程序在 Webforms 中时残留的 ContentPlaceHolder),但即使我在部分中使用它,当部分呈现时我们“低于”该部分,所以它不会做任何事。

我确实有一个 ViewModel 类。我可以为“CustomCss”创建一个属性并从部分设置/附加它(是的,这可能是错误的形式......),然后将它从布局中写入 HEAD 标记。但是,当我的部分执行此操作时,布局已经呈现,这意味着我们“低于” HEAD 标记。

从哲学上讲,我在这里不明白什么?虽然我的 CSS 问题是我的严重问题,但我正在尝试了解更大的点/架构。

【问题讨论】:

    标签: asp.net-mvc razor partial-views


    【解决方案1】:

    在 razor 中,相当于您正在寻找的内容称为 sections

    在您的_Layout.cshtml 文件中,您输入如下代码:

    @RenderSection("Scripts", false) // true = section required
                                     //false = section optional
    

    @RenderBody()
    

    然后在你的视图中你输入这样的代码

    @section Scripts
    {
       <!--
           razor and html markup placed here gets rendered in the "Scripts"
           section in _Layout.cshtml
        -->
    }
    <!-- code here goes in RenderBody()-->
    

    【讨论】:

    • 部分在功能上不等效。具体来说,您不能在局部视图中定义一个部分并期望它在“父”视图的布局中呈现。这只有在局部视图有自己的布局时才有效。
    • 好的,但是当我的部分执行时,我们已经“低于”“RenderSection”行。这仍然有效吗? (这不是,在我的代码中,虽然我承认我可能做错了什么。)
    • 是的,@Jens 上面解释的是我的问题。在部分中定义的部分没有达到所有备份到布局中。
    【解决方案2】:

    WebForms 和 MVC Views 的主要区别在于 WebForms 创建了一个对象树,由各种控件和其他部分组成。创建此树后,将通过递归地要求控件呈现自己来呈现页面。由于这种情况发生得很晚,因此您可以引用在插入控件之前出现的页面部分,因为该页面尚未呈现。

    另一方面,MVC Razor 视图是一次性执行的。 ViewEngine 被实例化,接收视图、视图数据和(可能)模型,并开始从上到下执行代码(或输出 HTML)。加载布局和渲染部分甚至不是必需的,而是完全可选的。而且由于该过程是从上到下的单通道,因此您无法进行反向引用,因为该部分已经完成,甚至可能已发送到浏览器。

    【讨论】:

    • 这是有道理的。那么,鉴于您描述的架构,我提出的问题的解决方案是什么(需要自定义 CSS 的部分)?
    • 是否包含 CSS 的逻辑必须存在于调用部分的视图中。如果它是有条件的,您可以在视图的一开始就决定是否需要部分并记住在本地布尔值中。或者您可以使用 HtmlHelper 函数做一些更复杂的事情。
    • 好吧,否则您根本无法有条件地加载 CSS。只需将它包含在您的全局(希望)最小化的 CSS 中,并限定 CSS 选择器,使其仅适用于部分视图内容。
    • 我不喜欢的是将部分模板代码与它需要的 CSS 分开。我喜欢这两个东西是同一个文件的想法,所以它是可移植的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    • 2012-05-02
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多