• [转].net core 通过ViewComponent封装控件 左侧菜单


    本文转自:http://www.cnblogs.com/BenDan2002/p/6224816.html

    我们在.net core中还使用了ViewComponent方式生成控件。ViewComponent也是asp.net core的新特性,是对页面部分的渲染,以前PartialView的功能,可以使用ViewComponent来实现。

    View Component包含2个部分,一个是类(继承于ViewComponent),和它返回的结果Razor视图(和普通的View视图一样)。

    我们还是来看一下以侧边菜单控件为例子,怎么创建一个ViewComponent。侧边菜单控件如下图:

    控件的主要逻辑是按照用户和应用程序代码,获取所有已经按照父子结构组织的菜单,传送到页面展示。

    上面已经提到,View Component包含2个部分,一个是类,这个类也继承于ViewComponent类。子控件最主要的是重写ViewComponent类的Invoke/InvokeAsync方法:

    复制代码
     1     public class SideMenuViewComponent : ViewComponent
     2     {
     3         private IMenuAppService service;
     4         public SideMenuViewComponent(IMenuAppService service)
     5         {
     6             this.service = service;
     7         }
     8 
     9         public IViewComponentResult Invoke(string appCode, UserInfo userInfo)
    10         {
    11             IEnumerable<MenuDto> menuItems = this.service.GetHierarchy(appCode, userInfo);
    12 
    13             return View("SideMenu", menuItems);
    14         }
    15     }
    复制代码

    再来看ViewComponent的第二部分,就是Razor视图,这里是SideMenu.cshtml:

    复制代码
     1 @using MicroStrutLibrary.Presentation.Web.Controls
     2 @using MicroStrutLibrary.AppService.Portal
     3 @using Microsoft.AspNetCore.Html
     4 
     5 @model  IEnumerable<MenuDto>
     6 @{
     7     var controlId = System.Guid.NewGuid().ToString("N");
     8 }
     9 
    10 @functions
    11 {
    12     public IHtmlContent RenderChildren(IEnumerable<MenuDto> menuItems)
    13     {
    14         string result = "<ul class="submenu" style="display: none;">";
    15 
    16         foreach (MenuDto itemInfo in menuItems)
    17         {
    18             var url = Url.Content(string.IsNullOrWhiteSpace(itemInfo.Url) ? "#" : itemInfo.Url);
    19             var icon = string.IsNullOrWhiteSpace(itemInfo.IconClass) ? "fa fa-list-ul" : itemInfo.IconClass;
    20             var leaf = (itemInfo.IsLeaf && (itemInfo.Children == null || itemInfo.Children.Count() < 1));
    21 
    22             result += "<li>";
    23             result += $"<a href="{Html.Raw(url)}" target="{itemInfo.Target}" title="{itemInfo.MenuDesc}" data-feature="{itemInfo.WinFeature}" data-leaf="{leaf.ToString().ToLower()}"><i class="${Html.Raw(icon)}"></i><span>{itemInfo.MenuName}</span></a>";
    24             if (!leaf)
    25             {
    26                 result += RenderChildren(itemInfo.Children).ToString();
    27             }
    28         }
    29 
    30         result += "</ul>";
    31         return new HtmlString(result);
    32     }
    33 }
    34 <div id="@(controlId)" class="jquery-accordion-menu red">
    35     <div class="jquery-accordion-menu-header">
    36     </div>
    37     <ul>
    38         @foreach (MenuDto itemInfo in Model)
    39         {
    40             var url = Url.Content(string.IsNullOrWhiteSpace(itemInfo.Url) ? "#" : itemInfo.Url);
    41             var icon = string.IsNullOrWhiteSpace(itemInfo.IconClass) ? "fa fa-list-ul" : itemInfo.IconClass;
    42             var leaf = (itemInfo.IsLeaf && (itemInfo.Children == null || itemInfo.Children.Count() < 1));
    43 
    44             <li>
    45                 <a href="@Html.Raw(url)" target="@itemInfo.Target" title="@itemInfo.MenuDesc" data-feature="@itemInfo.WinFeature" data-leaf="@(leaf.ToString().ToLower())">
    46                     <i class="@Html.Raw(icon)"></i>
    47                     <span>@itemInfo.MenuName</span>
    48                 </a>
    49                 @if (!leaf)
    50                 {
    51                     @RenderChildren(itemInfo.Children)
    52                 }
    53             </li>
    54         }
    55     </ul>
    56     <div class="jquery-accordion-menu-footer">
    57     </div>
    58 </div>
    59 <script>
    60     require(['jquery', 'accordionmenu'], function ($) {
    61         var $sidebar = $("#@(controlId)");
    62 
    63         $sidebar.jqueryAccordionMenu();
    64 
    65         $("a", $sidebar).click(function (e) {
    66             var $this = $(this);
    67 
    68             if (!$this.data("leaf")) {
    69                 e.preventDefault();
    70             } else {
    71                 var feature = $this.data("feature");
    72 
    73                 if (feature) {
    74                     e.preventDefault();
    75                     window.open($this.attr("href"), $this.attr("target"), feature);
    76                 }
    77             }
    78         });
    79         $("li", $sidebar).click(function () {
    80             $("li.active", $sidebar).removeClass("active");
    81             $(this).addClass("active");
    82         });
    83     });
    84 </script>
    复制代码

    Cshtml中,我们用到了@functions的写法,其实就是相当于在cshtml中编写cs的方法,一般这个方法要求返回的是IHtmlContent。

    进阶:资源性视图的应用

    按照以往的惯例,我们依旧还一个进阶,说明下ViewComponent中的cshtml作为嵌入的资源该如何写。

    其实做法和TagHelper是一样的。首先是嵌入式资源方式,需要在project.json中按照如下方式编写:

    "buildOptions": {

    "embed": [ "Components/**/*.cshtml", "TagHelpers/**/*.cshtml" ]

    }

    然后再写一个扩展方法,同上个文档的EmbeddedFileServiceCollectionExtensions,最后是在Startup.cs中使用这个扩展方法。

    因为我们的ViewComponet和TagHelper都在同一个WebControls项目中,因此进阶部分的代码根本不需要再写了。这里再重复说明的原因是,在没有写过上述代码的情况下,如何将ViewComponent的Cshtml作为嵌入的资源。

    面向云的.net core开发框架

  • 相关阅读:
    【noiOJ】p1759
    【noiOJ】p1481
    【noiOJ】p6253
    【noiOJ】p1794
    【noiOJ】p1776
    【noiOJ】p8210
    【noiOJ】p7939
    【noiOJ】p7914(..)
    【noiOj】p8207(233)
    鸟哥的linux私房菜——第六章学习(Linux文件与目录管理)
  • 原文地址:https://www.cnblogs.com/freeliver54/p/6249706.html
Copyright © 2020-2023  润新知