zoukankan      html  css  js  c++  java
  • view components介绍

    view components介绍

    在ASP.NET MVC 6中,view components (VCs) 功能类似于虚拟视图,但是功能更加强大。 VCs兼顾了视图和控制器的优点,你可以把VCs 看作一个Mini 控制器。它负责控制应用中的某一功能模块,例如:

    • 动态导航菜单
    • 标签云
    • 登录面板
    • 购物车
    • 最近文章
    • 博客侧边栏

    假如使用VC 创建了登录面板,可以在很多场景中调用,例如:

    • 用户没有登录
    • 用户已登录,需要退出使用其他帐号登录或者管理其他帐号。
    • 如果当前登录角色为管理员,渲染管理员登录面板

    你可以根据用户的需求获取数据进行渲染。添加VC到需要该视图控件的页面。

    VC 包含两部分,类 (一般继承于ViewComponent) 和调用VC类中方法的Razor 视图。类似于ASP.NET 控制器, VC 可以作为POCO使用,但是更多用户倾向于使用从 VewComponent中继承而来的方法和属性。

    VC的创建方式有:

    • 继承ViewComponent.
    • 拥有 [ViewComponent] 属性,或者从拥有 [ViewComponent]属性派生的类。
    • 创建名称已ViewComponent为后缀的类。

    和controllers相同,VCs 必须是公开、非嵌套和非抽象的类。

    添加view component 类

    1. 创建名为ViewComponents的文件夹,View component 类可以包含在工程中的任何文件夹下。

    2. 在ViewComponents 文件夹下创建PriorityListViewComponent.cs 类。.

    3. 使用以下代码替代PriorityListViewComponent.cs 文件原有代码:

    复制代码
    using System.Linq;
    using Microsoft.AspNet.Mvc;
    using TodoList.Models;
    
    namespace TodoList.ViewComponents
    {
      public class PriorityListViewComponent : ViewComponent
      {
        private readonly ApplicationDbContext db;
    
        public PriorityListViewComponent(ApplicationDbContext context)
        {
          db = context;
        }
    
        public IViewComponentResult Invoke(int maxPriority)
        {
          var items = db.TodoItems.Where(x => x.IsDone == false &&
                                            x.Priority <= maxPriority);
    
          return View(items);
        }
      }
    }
    复制代码

    代码注释:

    · 因为PriorityListViewComponent 类继承于ViewComponent,运行时将通过字符串"PriorityList" 从View中引用该类。在后续章节将会进行详细阐述。

    · [ViewComponent] 属性用于设置引用VC的别名,例如,创建名称为XYZ的类,我们可以通过以下代码设置其引用别名:

    [ViewComponent(Name = "PriorityList")]
    public class XYZ : ViewComponent

    · 组件使用构造注入器使数据内容生效,类似于 Todo 控制器的功能。

    · 调用View中的公开方法,可以传递任意数量的参数。在异步版本中, InvokeAsync是可用的。在后续章节中我们将提及InvokeAsync 和多参数的使用方法。在之前的代码中,公开方法的返回值为代办事项(ToDoItems),优先级不低于maxPriority。

    添加视图控件

    1. 在ViewsTodo 文件夹下创建Components文件夹,注意这个文件夹需要命名为Components。

    2. 在ViewsTodoComponents 文件夹下创建PriorityList 文件夹。文件夹名称必须和view component 类名称一致。或者类名去除后缀名称(如果在创建类时遵循惯例使用ViewComponent 作为后缀)。如果使用了ViewComponent属性。

    3. ViewsTodoComponentsPriorityList  文件夹下创建Default.cshtml Razor 视图,添加以下标记:

    复制代码
    @model IEnumerable<TodoList.Models.TodoItem>
    
    <h3>Priority Items</h3>
    <ul>
        @foreach (var todo in Model)
        {
            <li>@todo.Title</li>
        }
    </ul>
    复制代码

    Razor 视图包含并且显示了 TodoItems。如果 VC 调用方法没有传递视图的名称 (如例子中所示),那么默认情况下则调用视图名称对于方法。在后续的文章中,将阐述如何传递视图名称。

    views odoindex.cshtml 视图底部添加包含有调用PriorityListViewComponent的div:

    复制代码
    @model IEnumerable<TodoList.Models.TodoItem>
    
    <h3>Priority Items</h3>
    <ul>
        @foreach (var todo in Model)
        {
            <li>@todo.Title</li>
        }
    </ul>
    复制代码

    标记 @await Component.InvokeAsync() 表示该语法用于调用VC。第一个参数是我们要调用的组件名称。其余参数参数传递给该VC。在这个例子中,我们传递“1”作为过滤的优先级。InvokeAsync 方法可以包含任意数量的参数。

    以下图片显示了优先级列表:

    复制代码
    @{
      ViewBag.Title = "ToDo Page";
    }
    
    <div class="jumbotron">
      <h1>ASP.NET vNext</h1>
    </div>
    
    <div class="row">
      <div class="col-md-4">
        @if (Model.Count == 0)
        {
          <h4>No Todo Items</h4>
        }
        else
        {
          <table>
            <tr><th>TODO</th><th></th></tr>
            @foreach (var todo in Model)
            {
              <tr>
                <td>@todo.Title </td>
                <td>
                  @Html.ActionLink("Details", "Details", "Todo", new { id = todo.Id }) |
                  @Html.ActionLink("Edit", "Edit", "Todo", new { id = todo.Id }) |
                  @Html.ActionLink("Delete", "Delete", "Todo", new { id = todo.Id })
                </td>
              </tr>
            }
          </table>
                  }
        <div>@Html.ActionLink("Create New Todo", "Create", "Todo") </div>
      </div>
    
      <div class="col-md-4">
        @Component.Invoke("PriorityList", 1)   
      </div>
    
    </div>
    复制代码

    image

    注意: VC通常被添加到 ViewsShared 文件夹下,因为它并不仅仅是controller。

    添加InvokeAsync 到优先级组件

    通过以下代码更新PriorityListViewComponent类:

    复制代码
    using System.Linq;
    using Microsoft.AspNet.Mvc;
    using TodoList.Models;
    using System.Threading.Tasks;
    
    namespace TodoList.ViewComponents
    {
        public class PriorityListViewComponent : ViewComponent
        {
            private readonly ApplicationDbContext db;
    
            public PriorityListViewComponent(ApplicationDbContext context)
            {
                db = context;
            }
    
            // Synchronous Invoke removed.
            
            public async Task<IViewComponentResult> InvokeAsync(int maxPriority, bool isDone)
            {
                string MyView = "Default";
    
                // If asking for all completed tasks, render with the "PVC" view.
                if (maxPriority > 3 && isDone == true)
                {
                    MyView = "PVC";
                }
    
                var items = await GetItemsAsync(maxPriority, isDone);
    
                return View(MyView, items);
            }
    
            private Task<IQueryable<TodoItem>> GetItemsAsync(int maxPriority, bool isDone)
            {
                return Task.FromResult(GetItems(maxPriority, isDone));
    
            }
            private IQueryable<TodoItem> GetItems(int maxPriority, bool isDone)
            {
                var items = db.TodoItems.Where(x => x.IsDone == isDone &&
                                                    x.Priority <= maxPriority);
    
                string msg = "Priority <= " + maxPriority.ToString() +
                             " && isDone == " + isDone.ToString();
                ViewBag.PriorityMessage = msg;
    
                return items;
            }
    
        }
    }
    复制代码

    注意: 这里移除了用于同步的Invoke 方法,使用更加强大的asynchronous方法替代。

    修改 VC 视图显示优先级信息:

    复制代码
    @model IEnumerable<TodoList.Models.TodoItem>
    
    <h4>@ViewBag.PriorityMessage</h4>
    <ul>
        @foreach (var todo in Model)
        {
            <li>@todo.Title</li>
        }
    </ul>
    复制代码

    最后,更新 views odoindex.cshtml 视图文件:

    复制代码
    @* Markup removed for brevity. *@
        
        <div class="col-md-4">
            @await Component.InvokeAsync("PriorityList", 2, true)
        </div>
    </div>
    复制代码

    以下图片展示了PriorityListViewComponent类和Index视图的修改效果:

    image

     

    指定视图名称

    一些复杂的VC在某些情况下也许需要去指定特定的视图,以下代码是通过InvokeAsync 方法指定视图的方法:

    复制代码
    public async Task<IViewComponentResult> InvokeAsync(int maxPriority, bool isDone)
    {
        string MyView = "Default";
    
        // If asking for all completed tasks, render with the "PVC" view.
        if (maxPriority > 3 && isDone == true)
        {
            MyView = "PVC";
        }
    
        var items = await GetItemsAsync(maxPriority, isDone);
    
        return View(MyView, items);
    }
    复制代码

    更改 ViewsTodoComponentsPriorityListDefault.cshtml 为 ViewsTodoComponentsPriorityListPVC.cshtml 视图。更改PVC视图控件来验证它的使用:

    复制代码
    @model IEnumerable<TodoList.Models.TodoItem>
    
    <h2> PVC Named Priority Component View</h2>
    <h4>@ViewBag.PriorityMessage</h4>
    <ul>
        @foreach (var todo in Model)
        {
            <li>@todo.Title</li>
        }
    </ul>
    复制代码

    最后,需要更新 ViewsTodoIndex.cshtml 文件:

    刷新页面查看更改效果。

    在MVC6中,更改controller(或其他任何代码)时,不需要重新编译或重新运行应用,仅需要保存代码并且刷新页面即可。

    以上即为今天希望和大家分享的view components知识,下一篇文章我们将介绍以下两部分内容:

    • 向视图中添加服务方法。
    • 发布应用到公有云方法。

    敬请期待。

    原文链接:http://www.asp.net/vnext/overview/aspnet-vnext/vc

  • 相关阅读:
    网络运维与管理2013超值精华本
    [置顶] JQuery实战总结三 标签页效果图实现
    ASP.NET 联想控件(Autocomplete)测试可用 ascx
    python手记(48)
    [Android]解决3gwap联网失败:联网请求在设置代理与直连两种方式的切换
    「两」创建一个带 ssh 镜座服务(修订版)--采用 Dockerfile 创
    美国同事实习
    javascript相框echarts插件实现酷立方效果图的人
    Docker container 集装箱说明
    tinkerpop(1) 地图数据库console科研
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/4217318.html
Copyright © 2011-2022 走看看