ViewComponenthtml
一、View 组件介绍安全
在ASP.NET CORE MVC中,View组件有点相似于partial views,可是他们更强大,View组件不能使用model binding,当你调用它的时候仅仅依赖与你提供的数据
一个View组件特色:mvc
.呈现一大块而不是一个总体的响应。
.包含在控制器和视图之间发现的相同的分离问题和可测试行优势。
.能够包含参数和业务逻辑。
.一般从布局页面调用。asp.net
你能够在任何可重复使用的渲染逻辑的部分视图中用视图组件来替换。async
例如:函数
.动态导航菜单布局
.标签云测试
.登录面板编码
.购物车spa
.最近发表的文章
.侧栏内容在一个典型的博客
.登录的面板信息能够显示在每个页面上,并显示要注销或登录的连接,具体取决于用户的登录状态
视图组件有两部分组成:类(一般派生自ViewComponent)和返回结果(一般为视图). 像控制器
同样,视图组件能够是POCO,但大多数开发人员都但愿利用从ViewComponent派生的方法和属性
二、建立一个View组件
本节包含建立一个视图组件。在本文的后面,咱们将详细检查每一个步骤并建立一个视图组件。
2.1 、View Component类
一个View组件的类能够经过下面方式建立:
.继承ViewComponent
.使用[ViewComponent]attribute 修饰的类,或者继承自一个[ViewComponent]attribute类的子类。
.建立一个以ViewComponent结尾的类。
像控制器同样,View组件必须是公共的、非嵌套的,和非抽象类。视图组件名称是删除"ViewComponent" 后缀的类名称。
也可使用ViewComponentAttribute.Name属性显式指定它。
2.二、View Component 类
.支持构造函数注入
.不参与控制器的生命周期,这意味着你不能在视图组件中使用过滤器
2.三、View Component方法
视图组件在InvokeAsync方法中定义其逻辑,该方法返回IViewComponentResult.调用视图组件直接用参数,而不是模型
绑定。视图组件从不直接处理请求。一般,视图组件初始化模型,并经过调用View方法将其传递给视图。
老是来讲,视图组件方法以下:
.定义一个InvokeAsync 方法返回一个IViewComponentResult
.一般,经过调用ViewComponent View方法来初始化模型并将其传给视图。
.参数来自调用方法,而不是HTTP,没有模型绑定
.不能直接做为HTTP端点访问,他们是经过代码调用(一般在视图中)。视图组件从不处理请求。
.在签名上重装,而不是来自当前HTTP请求的任何详细信息
2.四、View 搜索路径
运行时View经过搜索下列路径:
.Views/<controller_name>/Components/<view_component_name>/<view_name>
.Views/Shared/Components/<view_component_name>/<view_name>
建立视图组件结果或调用VIew方法时,能够指定不一样的视图名称。
咱们建议你为视图文件命名为Default.cshtml,并使用Views/Shared/Components/<view_component_name>/<view_name>路径
此示例中使用的PriorityList视图组件使用Views/Shared/Components/PriorityList/Default.cshtml做为视图组件视图。
一个视图组件默认的名称是Default.cshtml 而且使用Views/Shared/Components/<view_component_name>/<view_name> 路径.
在这个例子中咱们使用PriorityList视图组件Views/Shared/Components/PriorityList/Default.cshtml
2.四、调用一个视图组件
在View视图内经过以下调用视图组件:
@Component.InvokeAsync("Name of view component", <anonymous type containing parameters>)
参数将传递给InvokeAsync方法。在文章中开发的PriorityList视图组件是从Views/Todo/Index.cshtml视图中调用的。
在下面,InvokeAsync方法调用两个参数:
@await Component.InvokeAsync("PriorityList", new { maxPriority = 4, isDone = true })
经过Tag Helper调用视图组件:
对于asp.net core 1.1和更高版本,你能够做为tagHelper调用一个视图组件。
<vc:priority-list max-priority="2" is-done="false">
</vc:priority-list>
上面代码中,PriorityList视图组件被转化成priority-list.视图组件的参被转化成小写短横线属性。
调用视图组件的标签助手使用<vc> </ vc>元素。 视图组件指定以下:
<vc:[view-component-name]
parameter1="parameter1 value"
parameter2="parameter2 value">
</vc:[view-component-name]>
注意: 为了使用View Component做为Tag Helper,必须使用@addTagHelper指令注册包含View Component的程序集。例如,
若是你的View Component位于名为"MyWebApp"的程序集,请将如下指令添加到_ViewImports.cshtml文件中:
@addTagHelper *, MyWebApp
本教程中使用的InvokeAsync方法:
@await Component.InvokeAsync("PriorityList", new { maxPriority = 4, isDone = true })
标签助手标记
<vc:priority-list max-priority="2" is-done="false">
</vc:priority-list>
在上面的示例中,PriorityList视图组件成为priority-list。
在Controller中直接调用一个组件
视图组件一般从视图调用,但您能够直接从控制器方法调用他们。虽然视图组件不定义端点(如控制器),但你能够轻松
实现返回ViewComponentResult内容的控制器操做。
下面代码,View 组件直接经过控制器调用:
public IActionResult IndexVC()
{
return ViewComponent("PriorityList", new { maxPriority = 3, isDone = false });
}
2.五、建立一个ViewComponent
在代码中注意以下几点:
.View Component 类能包含到项目任何目录下.
.由于类名PriorityListViewComponent以ViewComponent结尾,运行时使用字符串"PriorityList"
稍后将会作详细解释.
.[ViewComponent]能改变名字引用一个ViewComponent。例如,咱们能够命名XYZ类,并应用ViewComponent attribute
[ViewComponent(Name = "PriorityList")]
public class XYZ : ViewComponent{}
.上面的[ViewComponent]特性告诉ViewComponent选择器使用名称为PriorityList 当视图查找相关联的组件时。
并从视图引用类的组件时使用字符串"PriorityList"
.组件使用了依赖注入,确保数据上下文是可用的。
.InvokeAsync是公开的方法能够直接从视图中调用,它能够传入任意数量的参数。
.InvokeAsync方法返回知足isDone和maxPriority参数的ToDo项集合
2.六、建立视图组件 Razor View
.建立Views/Shared/Components 文件夹.这个文件夹的名字必须是Components。
.建立Views/Shared/Components/PriorityList 文件夹,这个文件夹名称必须和ViewComponent类名称相同,或者类名减去后缀
若是你使用了ViewComponet属性,则类名必须匹配该属性.
.建立一个 Views/Shared/Components/PriorityList/Default.cshtml Razor view:
@model IEnumerable<ViewComponentSample.Models.TodoItem>
<h3>Priority Items</h3>
<ul>
@foreach (var todo in Model)
{
<li>@todo.Name</li>
}
</ul>
Razor View 返回一个列表并显示他们.若是这个View Component 的InvokeAsync方法没有传递一个View的名字,根据契约Default视图名字将被使用。
在稍后咱们将介绍如何传递一个视图的名字, 要覆盖特定控制器的默认样式,请将视图添加到特定于控制器的视图文件夹(例如Views / Todo / Components / PriorityList / Default.cshtml)。
将包含调用优先级列表组件的div添加到Views/Todo/index.cshtml文件的底部:
<div >
@await Component.InvokeAsync("PriorityList", new { maxPriority = 2, isDone = false })
</div>
@await Component.InvokeAsync 展现了如何调用ViewComponent语法.第一个参数是咱们想要调用视图组件的名称。后续参数传给组件,
InvokeAsync能够接受任意数量的参数能够接受任何数量的参数。
你也能够经过Controller直接调用。
public IActionResult IndexVC()
{
return ViewComponent("PriorityList", new { maxPriority = 3, isDone = false });
}
指定一个View名称
复杂的视图组件有时候可能须要指定一些非默认视图。下面代码显示了如何从InvokeAsync方法中指定PVC视图。
更新PriorityListViewComponent类中的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);
}
复制Views/Shared/Components/PriorityList/Default.cshtml文件,重命名为Views/Shared/Components/PriorityList/PVC.cshtml
在PVC.cshtml中添加下面代码:
@{
ViewData["Title"] = "Default";
}
@model IEnumerable<ViewComponentSimple.ViewComponents.TodoItem>
<h3>To do PVC View</h3>
<ul>
@foreach (var todo in Model)
{
<li>@todo.Name</li>
}
</ul>
运行应用程序,并验证PVC视图。
检查视图路径
.将priority参数更改0,以便不返回PVC视图。
.临时将Views/Todo/Components/PriorityList/Default.cshtml重命名为1Default.cshtml。
.运行App你会获得下面错误:
.复制 Views/Todo/Components/PriorityList/1Default.cshtml 到 Views/Shared/Components/PriorityList/Default.cshtml.
.向共享视图中添加一些标记,以指示视图来自共享文件。
.测试共享文件中视图组件.
若是你想确保编译时类型安全,你能够用类名去替换硬编码(不用字符串).建立一个View视图不适用"ViewComponent" 后缀
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ViewComponentSample.Models;
namespace ViewComponentSample.ViewComponents
{
public class PriorityList : ViewComponent
{
private readonly ToDoContext db;
public PriorityList(ToDoContext context)
{
db = context;
}
public async Task<IViewComponentResult> InvokeAsync(
int maxPriority, bool isDone)
{
var items = await GetItemsAsync(maxPriority, isDone);
return View(items);
}
private Task<List<TodoItem>> GetItemsAsync(int maxPriority, bool isDone)
{
return db.ToDo.Where(x => x.IsDone == isDone &&
x.Priority <= maxPriority).ToListAsync();
}
}
}
使用nameof操做符:
@using ViewComponentSample.Models
@using ViewComponentSample.ViewComponents
@model IEnumerable<TodoItem>
<h2>ToDo nameof</h2>
<!-- Markup removed for brevity. -->
}
</table>
<div>
@await Component.InvokeAsync(nameof(PriorityList), new { maxPriority = 4, isDone = true })
</div>
原文:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/views/view-components