原文: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 == " + isDone.ToString();
ViewBag.PriorityMessage = msg; return items;
} }
}
注意: 同步的Invoke方法被移除了. 当调用数据库的时候使用异步InvokeAsync是最佳实践.

更新VC Razor视图如下 :

@model IEnumerable<TodoList.Models.TodoItem>

<h4>@ViewBag.PriorityMessage</h4>
<ul>
@foreach (var todo in Model)
{
<li>@todo.Title</li>
}
</ul>

最后, 更新views\todo\index.cshtml 视图文件:

    @* Markup removed for brevity. *@

    <div class="col-md-4">
@await Component.InvokeAsync("PriorityList", 2, true)
</div>
</div>

指定view的名字

一个复杂的VC可能会根据不同的条件指定使用非默认的视图. 下面的代码展示如何指定view的名字:

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

复制 Views\Todo\Components\PriorityList\Default.cshtml 文件到Views\Todo\Components\PriorityList\PVC.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>

最后, 更新 Views\Todo\Index.cshtml :

@await Component.InvokeAsync("PriorityList",  4, true)

注入服务到视图中去

ASP.NET MVC 6 支持注入服务到视图中使用. 服务必须是非抽象和公开的. 在这个例子中, 我们穿件一个简单的类暴露todo的数量, 完成的数量等.

    1. 创建一个文件夹名为Services,添加一个名为StatisticsService.cs 的文件.

The StatisticsService class:

using System.Linq;
using System.Threading.Tasks;
using TodoList.Models; namespace TodoList.Services
{
public class StatisticsService
{
private readonly ApplicationDbContext db; public StatisticsService(ApplicationDbContext context)
{
db = context;
} public async Task<int> GetCount()
{
return await Task.FromResult(db.TodoItems.Count());
} public async Task<int> GetCompletedCount()
{
return await Task.FromResult(
db.TodoItems.Count(x => x.IsDone == true));
} public async Task<double> GetAveragePriority()
{
return await Task.FromResult(
db.TodoItems.Average(x =>
(double?)x.Priority) ?? 0.0);
}
}
}
  1. 更新Index视图. 在最上面添加如下注入语句:

    @inject TodoList.Services.StatisticsService Statistics

    在下面调用StatisticsService:

    <div>@Html.ActionLink("Create New Todo", "Create", "Todo") </div>
    </div> <div class="col-md-4">
    @await Component.InvokeAsync("PriorityList", 4, true) <h3>Stats</h3>
    <ul>
    <li>Items: @await Statistics.GetCount()</li>
    <li>Completed:@await Statistics.GetCompletedCount()</li>
    <li>Average Priority:@await Statistics.GetAveragePriority()</li>
    </ul>
    </div>
    </div>

    完整代码如下:

    @inject TodoList.Services.StatisticsService Statistics
    @{
    ViewBag.Title = "Home 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">
    @await Component.InvokeAsync("PriorityList", 4, true) <h3>Stats</h3>
    <ul>
    <li>Items: @await Statistics.GetCount()</li>
    <li>Completed:@await Statistics.GetCompletedCount()</li>
    <li>Average Priority:@await Statistics.GetAveragePriority()</li>
    </ul>
    </div>
    </div>
  2. Startup.cs 文件中注册StatisticsService类:

    // This method gets called by the runtime.
    public void ConfigureServices(IServiceCollection services)
    {
    // Add EF services to the services container.
    services.AddEntityFramework(Configuration)
    .AddSqlServer()
    .AddDbContext<ApplicationDbContext>(); // Add Identity services to the services container.
    services.AddDefaultIdentity<ApplicationDbContext, ApplicationUser, IdentityRole>(Configuration); // Add MVC services to the services container.
    services.AddMvc(); services.AddTransient<TodoList.Services.StatisticsService>();
    }
 

[译]View components and Inject in ASP.NET MVC 6的更多相关文章

  1. ASP.NET MVC 6 一些不晓得的写法

    今天在看 Scott Guthrie 的一篇博文<Introducing ASP.NET 5>,在 MVC 6 中,发现有些之前不晓得的写法,这边简单记录下,算是对自己知识的补充,有些我并 ...

  2. [转]ASP.NET MVC 入门5、View与ViewData

    view在MVC模式中与用户进行最直接的接触,它负责数据的呈现.这里要注意一点就是,view只是负责数据的呈现,所以我们应该要尽量让view中不涉及业务逻辑的处理. 我们来添加一个Blog首页的vie ...

  3. ASP.NET MVC Overview

    ASP.NET MVC Overview The Model-View-Controller (MVC) architectural pattern separates an application  ...

  4. 【转】ASP.NET MVC 的最佳实践

    [This post is based on a document authored by Ben Grover (a senior developer at Microsoft). It is ou ...

  5. ASP.Net Mvc 5 学习记录2015-9-9

    我之前一直都是学习和开发都采用ASP.Net WebForm,对MVC的一直都是一知半解,最初以为ASP.Net WebForm的N层架构就是MVC.其实N层架构设计思想是"高内聚,低耦合& ...

  6. 自学MVC看这里——全网最全ASP.NET MVC 教程汇总

    MVC架构已深得人心,微软也不甘落后,推出了Asp.net MVC.小编特意整理博客园乃至整个网络最具价值的MVC技术原创文章,为想要学习ASP.NET MVC技术的学习者提供一个整合学习入口.本文从 ...

  7. 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC

    系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 七天学会ASP.NET MVC (三)— ...

  8. 微冷的雨ASP.NET MVC之葵花宝典(MVC)

    微冷的雨ASP.NET MVC之葵花宝典 By:微冷的雨 第一章 ASP.NET MVC的请求和处理机制. 在MVC中: 01.所有的请求都要归结到控制器(Controller)上. 02.约定优于配 ...

  9. 新作《ASP.NET MVC 5框架揭秘》正式出版

    ASP.NET MVC是一个建立在ASP.NET平台上基于MVC模式的Web开发框架,它提供了一种与Web Form完全不同的开发方式.ASP.NET Web Form借鉴了Windows Form基 ...

随机推荐

  1. hdu 5229 找规律

    假设选择了字符串a和b: 假设两人都按照最聪明的策略,那么观察一下可以找出规律:当a和b的字符串长度之和为奇数的时候zcc会败. 另外当a==b的时候zcc也会败(当时做的时候忘了这个了T^T) 接下 ...

  2. Struts 2 Learning

    目录 . J2EE简介 . JAVA EE应用的分层模型 . 搭建Struts2 Demo应用 . struts2流程 . struts2的常规配置 . 实现Action . 配置Action . 配 ...

  3. Getshell Via phpmyadmin SQL Execution In /import.php To Write Evil Webshell File Into Disk

    目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 phpMyAdmin 是一个以PHP为基础,以Web-Base方式架构在网站主机上 ...

  4. python——代码编码格式转换

    最近刚换工作不久,没太多的时间去整理工作中的东西,大部分时间都在用来熟悉新公司的业务,熟悉他们的代码框架了,最主要的是还有很多新东西要学,我之前主要是做php后台开发的,来这边之后还要把我半路出家的前 ...

  5. 帝国cms制作手机网站

    1.操作前,我们需要先对网站数据库进行备份. 接下来我们添加手机站的模板组.点击"模板", 选择"模板组管理"中的"导入/导出模板组",然后 ...

  6. OpenGLES入门笔记三

    在入门笔记一中比较详细的介绍了顶点着色器和片面着色器. 在入门笔记二中讲解了简单的创建OpenGL场景流程的实现,但是如果在场景中渲染任何一种几何图形,还是需要入门笔记一中的知识:Vertex Sha ...

  7. spring---aop 配置

    第一种:注解配置AOP 注解配置AOP(使用 AspectJ 类库实现的),大致分为三步: 1. 使用注解@Aspect来定义一个切面,在切面中定义切入点(@Pointcut),通知类型(@Befor ...

  8. Microsoft SQL Server Management Studio ------------------------------ 附加数据库 对于 服务器

    http://zhidao.baidu.com/link?url=didvEEY86Kap_F9PnRAJMGoLXv63IW1fhElfiOpkkmalJ9mvZoqNULlGKcGHN31y_4z ...

  9. 用js实现QQ自定义在线图片

    用JS实现,具体步骤如下: 1) 申请代码 <a target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin ...

  10. git 简明使用手册

    git 使用简明手册     git 是由Linus Torvalds领衔开发的一款开源.分布式版本管理系统,显然,git最初是为了帮助管理Linux内核开发而开发的版本控制系统. 版本控制系统本身并 ...