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

介绍view components

view components (VCs) 类似于partial views, 但是VCs更加强大. 可以简单的把VC想象成一个mini的控制器.当你认为使用partial太复杂的时候你可以考虑使用VCs,例如:

  • 动态导航菜单Dynamic navigation menus
  • 标签云(从数据库获取数据)
  • 登录面板
  • 购物车
  • 最近发布的文章
  • 博客的其它边栏

VC由两部分组成, 继承自ViewComponent的类和Razor视图.

View Component类可以通过下面的方式创建:

  • 继承ViewComponent.
  • [ViewComponent] attribute 装饰类, 或者继承在一个被[ViewComponent]装饰的类.
  • 创建一个类, 类名以ViewComponent结尾.

和控制器一样VCs必须是public的类.

添加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);
        }
      }
    }

备注:

  • 因为类名PriorityListViewComponentViewComponent 结尾, 在视图中我们可以使用字符串 "PriorityList".
  • [ViewComponent] attribute 被使用来改变他的引用名. 例如, 我们有一个类名为XYZ,  我们应用ViewComponent attribute:
    [ViewComponent(Name = "PriorityList")]
    public class XYZ : ViewComponent
    上面的[ViewComponent] attribute 告诉view component选择器当查找视图关联的component的使用 使用PriorityList, 在视图中使用字符串"PriorityList" 来关联相应的类.
  • component使用构造函数注入.
  • Invoke 暴露一个方法在相应的视图中被调用, invoke可以包含任意参数. Invoke对应的异步方法是InvokeAsync

添加 view component view

  1. 在 Views\Todo 文件夹下面创建文件夹名为Components. 注意了必须名为Components.
  2. Views\Todo\Components 文件夹下面创建文件夹名为PriorityList. 这个文件夹的名字必须和view component 类的名字匹配, 或者类名的前缀匹配(如果类名使用 ViewComponent 后缀). 如果你使用了ViewComponent attribute, 名字必须和attribute 名匹配. 
  3. 在 Views\Todo\Components\PriorityList 文件夹下创建Default.cshtml Razor视图文件 , 添加如下内容:
    @model IEnumerable<TodoList.Models.TodoItem>
    
    <h3>Priority Items</h3>
    <ul>
        @foreach (var todo in Model)
        {
            <li>@todo.Title</li>
        }
    </ul>
  4. views\todo\index.cshtml 文件中调用VC:
    @{
      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>
    @await Component.InvokeAsync() 是对应的异步方法. 第一个参数是要调用的component的名字. 后面的参数是传到component类的参数. 

注意: 一般来说View Component 视图加在Views\Shared 文件夹下, 因为VCs一般没有指定controller.

添加InvokeAsyn component

更新VC类如下:

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 == "

相关文章:

  • 2021-11-14
  • 2019-08-09
  • 2021-09-11
  • 2021-10-17
  • 2021-09-11
  • 2021-06-05
  • 2021-10-16
猜你喜欢
  • 2021-09-08
  • 2021-11-15
  • 2021-08-09
  • 2018-10-17
  • 2018-01-28
  • 2018-02-05
  • 2018-03-29
  • 2019-03-21
相关资源
相似解决方案