zoukankan      html  css  js  c++  java
  • asp.net core系列 42 Web 应用 分部视图

    一.分部视图

      对于MVC 视图和 Razor Pages 页面,都有分部视图功能。通常将 MVC 视图和 Razor Pages 页面统称为“标记文件”,下面会常提到该名词。使用分部视图的优势包括:(1) 将大型标记文件分解为更小的组件。(2) 减少跨标记文件中,常见标记内容的重复。

      建议:(1)不应使用分部视图来维护常见布局元素,常见布局元素应在 _Layout.cshtml 文件中指定,比如页头、页尾。(2)当需要呈现复杂逻辑或代码执行的应该使用视图组件。

      1.1 声明分部视图

        分部视图是在 Views 文件夹 (MVC) 或 Pages 文件夹 (Razor Pages) 中维护的 .cshtml 标记文件。在 ASP.NET Core MVC 中,控制器的 ViewResult 能够返回视图或分部视图。 在 ASP.NET Core 2.2 中 Razor Pages 的PageModel 可以返回 PartialViewResult分部视图。

        分部视图不会运行 _ViewStart.cshtml页,这涉及到布局以后再讲。分部视图的文件名通常以下划线 _ 开头,没有.cshtml.cs文件。

        

      1.2 引用分部视图

        在标记文件中,有多种方法可引用分部视图。 建议应用程序使用以下异步呈现方法之一:(1) 分部标记帮助程序。(2) 异步 HTML 帮助程序。 不建议使用同步HTML 帮助程序, 因为可能会出现死锁的情况, 同步方法以后版本中会删除,这里不再介绍。

        (1) 分部标记帮助程序

          分部标记帮助程序会异步呈现内容,并使用类似 HTML 的语法:

            <partial name="_PartialName" />

          当存在文件扩展名时,标记帮助程序会引用分部视图,该视图必须与调用分部视图的标记文件位于同一文件夹中:   

          <partial name="_PartialName.cshtml" />

          以下示例从应用程序根目录引用分部视图。 以 (~/) 或 (/) 开头的路径,指代应用程序根目录:

            Razor 页面CSHTML
            <partial name="~/Pages/Folder/_PartialName.cshtml" />
             <partial name="/Pages/Folder/_PartialName.cshtml" />
            MVC  CSHTML
            <partial name="~/Views/Folder/_PartialName.cshtml" />
            <partial name="/Views/Folder/_PartialName.cshtml" />
          使用相对路径的分部视图
          <partial name="../Account/_PartialName.cshtml" />

        

        (2) 异步 HTML 帮助程序

          使用 HTML 帮助程序时,最佳做法是使用 PartialAsync,同步是使用Partial(不建议使用同步)。PartialAsync 返回包含在 Task<TResult> 中的 IHtmlContent 类型。通过@await来引用该方法。

    Razor 页面CSHTML
    @await Html.PartialAsync("~/Pages/Folder/_PartialName.cshtml")
    @await Html.PartialAsync("/Pages/Folder/_PartialName.cshtml")
    mvc CSHTML
    @await Html.PartialAsync("~/Views/Folder/_PartialName.cshtml")
    @await Html.PartialAsync("/Views/Folder/_PartialName.cshtml")

          也可以使用 RenderPartialAsync 呈现分部视图。 此方法不返回 IHtmlContent。它将呈现的输出,直接流式传输到响应, 因此在某些情况下它可提供更好的性能。 因为该方法不返回结果,所以必须在 Razor 代码块内调用它:

    @{
        await Html.RenderPartialAsync("_AuthorPartial");
    }

      1.3 分部视图发现

        如果按名称(无文件扩展名)引用分部视图,则按所述顺序搜索以下位置:

             (1) Razor 页面

                      1.当前正在执行页面的文件夹

                      2.该页面文件夹上方的目录图

                      3./Shared

                      4./Pages/Shared

                      5./Views/Shared

               (2) MVC

                       1./Areas/<Area-Name>/Views/<Controller-Name>

                       2./Areas/<Area-Name>/Views/Shared

                       3./Views/Shared

                       4./Pages/Shared

          

      1.4 通过分部视图访问数据

        实例化分部视图时,它会获得父视图(主视图)的 ViewData 字典的副本。 在分部视图内,对数据所做的更新不会保存到父视图中 对分部视图中的 ViewData 更改,会在分部视图返回时丢失。

        以下示例演示如何将 ViewDataDictionary(ViewData 字典)的实例传递给分部视图:

        @await Html.PartialAsync("_PartialName", customViewData)

        还可将模型(实体对象)传入分部视图。 模型可以是自定义对象。

        @await Html.PartialAsync("_PartialName", model)

        

    二. 演示

      下面演示一个Razor的分部视图(MVC的参考官网示例)。示例中Pages/ArticlesRP/ReadRP.cshtml是主视图,Pages/Shared/_AuthorPartialRP.cshtml是第一个分部视图,传入“作者”。Pages/ArticlesRP/_ArticleSectionRP.cshtml 是第二个分部视图,传入ViewData字典和section模型二个参数,这二个参数是PartialAsync的方法重载。 三个文件结构如下:

      (1) 创建实体类

       public class Article
        {
            public string Title { get; set; }
    
            public string AuthorName { get; set; }
    
            public string PublicationDate { get; set; }
    
            public List<ArticleSection> Sections { get; set; }
        }
    
        public class ArticleSection
        {
            public string Title { get; set; }
            public string Content { get; set; }
        }

      (2)主视图

        public class ReadRPModel : PageModel
        {
            public Article Article { get; set; }
    
            public void OnGet()
            {
                Article = new Article()
                {
                    Title = "来自 <共享分部视图文件路径> 的分部视图",
                    AuthorName = "Abraham Lincoln",
                    PublicationDate= "1863 年 11 月 19 日中午 12:00:00",
                    Sections = new List<ArticleSection>() {
                             new ArticleSection (){ Title="第一节索引", Content="八十七年前..." },
                             new ArticleSection (){ Title="第二节索引", Content="如今,我们正在进行一场伟大的内战,考验着......" },
                             new ArticleSection (){ Title="第三节索引", Content="然而,从更广泛的意义上说,我们无法奉献..." },
                    }
                };
            }
        }
    @page
    @model ReadRPModel
    
    <h2>@Model.Article.Title</h2>
    
    @Model.Article.PublicationDate
    
    @* 将作者名字传到 PagesShared\_AuthorPartialRP.cshtml*@
    <p>---------------------------------第一个分部视图/Views/Shared/_AuthorPartial.cshtml</p>
    @await Html.PartialAsync("../Shared/_AuthorPartialRP.cshtml", Model.Article.AuthorName)
    
    
    <p></p>
    @*  Loop over the Sections and pass in a section and additional ViewData to
        the strongly typed PagesArticlesRP\_ArticleSectionRP.cshtml partial view. *@
    <p>---------------------------------第二个分部视图/Views/Shared/_ArticleSection.cshtml</p>
    @{
        var index = 0;
    
        @foreach (var section in Model.Article.Sections)
        {
            @await Html.PartialAsync("_ArticleSectionRP", section,
                                     new ViewDataDictionary(ViewData)
                                     {
                                         { "index", index }
                                     })
    
            index++;
        }
    }

      (3) 分部视图 _AuthorPartialRP.cshtm

    @* 将传过来的string类型映射*@
    @model string
    <div>
        <h3>@Model</h3>
    </div>

       (4) 分部视图 _ArticleSectionRP.cshtml 

    @using StudyRazorDemo.Models;
    
    @* 将传过来的对象映射到ArticleSection中*@
    @model ArticleSection
    
    <h3>@Model.Title Index: @ViewData["index"]</h3>
    <div>
        @Model.Content
    </div>
    <p></p>

       

      启动程序,运行http://localhost:42921/ArticlesRP/ReadRP,显示如下:

      参考资料

        ASP.NET Core 中的分部视图

       

  • 相关阅读:
    Python----路由器远程控制
    进程和线程的区别
    tengine日志切割-配置分钟级别日志自动切割
    grep每次读取多大的文本
    bc 进制间转换
    二分法猜数字
    What is the difference between HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR
    Nginx配置两份日志记录
    Nginx启动报错误unlink() “nginx.pid” failed (2: No such file or directory)
    Mysql 数据库crash恢复
  • 原文地址:https://www.cnblogs.com/MrHSR/p/10525099.html
Copyright © 2011-2022 走看看