zoukankan      html  css  js  c++  java
  • MVC教程八:母版页(布局页)视图

    一、母版页介绍和使用

    母版页的扩展名为".cshtml",也叫做视图布局页,它相当于网页的模板。在其他网页中,只要引用了母版页,母版页的页面内容就可以自动显示出来,设计者可以修改引用的母版页中预留的部分,其他部分保持不变,这样就可以使多个页面的风格保持一致,给网页设计带来了很大的方便。

    1、创建母版页视图的要点

    (1)、在Views的子文件夹Shared文件夹里面添加。

    (2)、以“_”前缀作为开头。

    (3)、以"Layout.cshtml"作为结束。

    2、MVC母版页里的三个功能点:

    (1)、RenderBody-子页面内容占位符。

    (2)、RenderPage-引用呈现一个页面。

    (3)、RenderSection-内容占位符。

    如果新建一个MVC程序,里面有没有使用母版页视图呢?查看Index视图:

    从上面的截图中可以看出,Index里面只有两个DIV,但是一个基本的网页代码需要有HTML、head、body等元素标签组成,但是这里面并没有。同时,浏览index视图:

    这时查看网页源代码:

    从上面的截图中可以看到有HTML、head、body等HTML元素,到这里可以看出,MVC中已经使用了母版页。MVC中默认使用Shared文件夹里面的_ViewStart.cshtml视图。

    二、RenderBody

    RenderBody的作用是子页面内容占位符。即母版页中使用了RenderBody的地方会使用子页面的内容来代替。以_Layout视图为例:

    在_Layout母版页中使用了RenderBody,所以运行的时候这部分内容将会被Index里面的内容代替。

    下面我们自己重新定义一个母版页,同时定义一个子页面来使用这个母版页来查看RenderBody的作用。

    1、添加母版页

    在Shared文件夹上面右键添加,选择MVC5布局页

    2、命名为_TestLayout

    生成的模板页代码如下:

    <!DOCTYPE html>
    
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>@ViewBag.Title</title>
    </head>
    <body>
        <div>
            @RenderBody()
        </div>
    </body>
    </html>

     3、修改母版页,修改后的母版页代码如下:

    <!DOCTYPE html>
    
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>@ViewBag.Title</title>
    </head>
    <body>
        <div>
            我是母版页,在子页面中不允许更改
            <!--内容页占位符-->
            @RenderBody()
        </div>
    </body>
    </html>

     4、创建子页面使用母版页

    在Home控制器里面添加一个ActionName为Test的Action方法,并添加视图:

    生成的Test视图如下图所示:

    注意:如果Layout=null,则表示不使用母版页视图。

    修改Test视图也,修改后的代码如下:

    @{
        ViewBag.Title = "Test";
        Layout = "~/Views/Shared/_TestLayout.cshtml";
    }
    
    <h2>Test</h2>
    <div>
        我是子页面-home控制器的Test方法
    </div>

     5、运行程序,浏览Test视图

    通过运行结果和查看网页源代码,可以看出是母版页和子页面组成的页面。

    三、RenderPage

    RenderPage:引用呈现一个页面,即在一个页面中引用呈现另外一个页面,也就是说另外一个页面是这个页面的一部分。

    以网页尾部布局为例说明RenderPage。

    1、在Shared文件夹里面新添加一个分部页,并命名为FooterPartial。

    2、修改分部也

    修改后的代码如下:

    <div>
        我是页脚
    </div>

    3、在母版页中使用分部页

    在RenderBody的下面使用RenderPage,RenderPage方法的参数如下图所示:

    从上图中可以看出,使用RenderPage()方法的时候,只需知道分部页的路径即可,修改后的母版页代码如下:

    <!DOCTYPE html>
    
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>@ViewBag.Title</title>
    </head>
    <body>
        <div>
            我是母版页,在子页面中不允许更改
            <!--内容页占位符-->
            @RenderBody()
            @RenderPage("_FooterPartial.cshtml")
        </div>
    </body>
    </html>

    4、运行结果

    四、RenderSection

    先来看下面一个例子:

    在Test视图里面添加一段脚本,修改后的Test视图代码如下:

    这是在运行程序,结果如下:

    通过运行结果发现脚本在视图内容呈现之前先执行了,这显示不是我们想要的效果。我们希望是在整个页面都加载完成之后再执行脚本。修改布局页代码如下:

    <!DOCTYPE html>
    
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>@ViewBag.Title</title>
    </head>
    <body>
        <div>
            我是母版页,在子页面中不允许更改
            <!--内容页占位符-->
            @RenderBody()
            <div style="color:blue">
                <p>
                    <!---->
                    @RenderSection("SectionContent")
                </p>
            </div>
            @RenderPage("_FooterPartial.cshtml")
        </div>
    
    </body>
    
    </html>

    子页面修改如下:

    运行结果:

    如果在母版页中定义了RenderSection,而在子页面中并没有对定义的RenderSection进行处理,那么结果是怎样的呢?

    从上图中可以看出,如果在子页面中没有对定义的RenderSection进行处理,程序运行的时候直接就报错了:SectionContent节未定义。如果不想处理RenderSection该如何修改呢?

    RenderSection方法截图如下:

    如果不想处理RenderSection,那么required参数设置为false就可以了,修改后的布局页代码如下:

    <!DOCTYPE html>
    
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>@ViewBag.Title</title>
    </head>
    <body>
        <div>
            我是母版页,在子页面中不允许更改
            <!--内容页占位符-->
            @RenderBody()
            <div style="color:blue">
                <p>
                    <!---->
                    @RenderSection("SectionContent",false)
                </p>
            </div>
            @RenderPage("_FooterPartial.cshtml")
        </div>
    
    </body>
    
    </html>

     这时在运行程序就可以正常运行了。

    通过上面的例子,我们可以使用下面的方法解决开头例子中遇到的问题:在body元素的结束标签上面定义RenderSection,这时无论在子页面的任何位置定义script脚本,都会在页面全部加载完成以后才执行脚本。

    布局页定义如下:

    五、总结

    1、RenderBody

    在Razor引擎中没有“母版页”,取而代之的是叫做“布局”的页面(_Layout.cshtml)放在了共享视图文件夹中。在这个页面中,会看到标签里面有这样一条语句:
    @RenderBody()
    其实它的作用和母版页中的服务器控件类似,当创建基于此布局页面的视图时,视图的内容会和布局页面合并,而新创建视图的内容会通过布局页面的@RenderBody()方法呈现在标签之间。
    这个方法不需要参数,而且只能出现一次。

    2、RenderPage

    从名称可以猜出来这个方法是要呈现一个页面。比如网页中固定的头部可以单独放在一个共享的视图文件中,然后在布局页面中通过这个方法调用,用法如下:
    @RenderPage("_FooterPartial.cshtml")
    可以带参数
    @RenderPage("_FooterPartial.cshtml",new {parm="my",parm2="you"})
    调用页面获取参数:
    //获取RenderPage()传递过来的参数
    @PageData["param"]

    3、RenderSection

    布局页面还有节(Section)的概念,也就是说:如果某个视图模板中定义了一个节,那么可以把它单独呈现出来,用法如下:
    @RenderBody()
    @RenderPage("_FooterPartial.cshtml")
    //模板里添加了一个节
    @RenderSection("head")
    当然还要在视图中定义节,否则会出现异常:
    @secion head{
    //do
    }
    为了防止因缺少节而出现异常,可以给RenderSection()提供第2个参数:
    @RenderSection("head",false)
    或者
    @if(IsSectionDefined("head"))
    {
    @RenderSection("head",false)
    }
    else
    {
    <p>head Section is not defined!</p>
    }

    4、@Html.Partial

    Partial每次都会创建自己的TextWriter实例并且把内容缓存到内存中,最后把所有write输出的内容发送到一个MvcString对象中。
    更多时候我们会使用@{Html.RenderPartial("Details");}而不是@Html.Partial。
    Html.RenderPartial()和@Html.Partial的区别:
    Html.RenderPartial()直接输出至当前HttpContext(因为是直接输出,所以性能好)。
    Html.Partial 将视图内容直接生成一个字符串并返回(相当于有个转义的过程)。
    RenderPage()和RenderPartial()的区别
    RenderPage()调用的页面只能使用其传递过去的数据。
    RenderPartial()是可以使用ViewData、model等数据的。
    如:@{Html.RenderPartial("BasicChart",model);}
    用这个重载可以在部分视图里使用强类型,然后在主视图中使用第二个参数传model过去。
    @{Html.RenderPartial("BasicChart",ViewData["myData"]);}

  • 相关阅读:
    《人月神话》读后感
    软件工程心得体会(十一)
    Arch + Win10 EFI 引导重装记录
    BurpSuite 的使用
    Wireshark 的使用
    Android 中的反调试技术
    IDA 对 so 的动态调试
    Smail 中的一些点
    IDA 对 SO 的逆向
    动态调试smali代码
  • 原文地址:https://www.cnblogs.com/dotnet261010/p/8904778.html
Copyright © 2011-2022 走看看