9.2.4 .net core 經過ViewComponent封裝控件

咱們在.net core中還使用了ViewComponent方式生成控件。ViewComponent也是asp.net core的新特性,是對頁面部分的渲染,之前PartialView的功能,可使用ViewComponent來實現。 html

View Component包含2個部分,一個是類(繼承於ViewComponent),和它返回的結果Razor視圖(和普通的View視圖同樣)。 jquery

 

咱們仍是來看一下以側邊菜單控件爲例子,怎麼建立一個ViewComponent。側邊菜單控件以下圖: json

控件的主要邏輯是按照用戶和應用程序代碼,獲取全部已經按照父子結構組織的菜單,傳送到頁面展現。 app

上面已經提到,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: asp.net

 

 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。ide

 

進階:資源性視圖的應用 ui

按照以往的慣例,咱們依舊還一個進階,說明下ViewComponent中的cshtml做爲嵌入的資源該如何寫。 this

其實作法和TagHelper是同樣的。首先是嵌入式資源方式,須要在project.json中按照以下方式編寫: url

"buildOptions": {

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

}

而後再寫一個擴展方法,同上個文檔的EmbeddedFileServiceCollectionExtensions,最後是在Startup.cs中使用這個擴展方法。

由於咱們的ViewComponet和TagHelper都在同一個WebControls項目中,所以進階部分的代碼根本不須要再寫了。這裏再重複說明的緣由是,在沒有寫過上述代碼的狀況下,如何將ViewComponent的Cshtml做爲嵌入的資源。

 

面向雲的.net core開發框架

相關文章
相關標籤/搜索