ASP.NET Core 3.x 入门(三)View Component
此入门教程是记录下方参考资料视频的学习过程
开发工具:Visual Studio 2019
参考资料:https://www.bilibili.com/video/BV1c441167KQ
API文档:https://docs.microsoft.com/zh-cn/dotnet/api/?view=aspnetcore-3.1
目录
小例子
在 Index 主页添加一个统计信息
-
为什么 Partial View 不行?
因为没法添加业务逻辑 -
如果在 Controller 里面写呢?
那就无法到处复用 -
Child Action 呢?
开销太大,它也需要走完整个 Controller 的生命周期 -
就像 Partial View ,但是还带有一个迷你的 Controller ,在这里面也可以写业务逻辑
-
可以使用 Razor 语法来渲染 View Component
在项目路径下新建 ViewComponents
文件夹,所有的 View Component 都在这个文件夹下
我们需要显示 CompanySummary ,所以在 ViewComponents 目录下新建 CompanySummaryComponent
类
public class CompanySummaryViewComponent : ViewComponent
{
#region 依赖注入
private readonly IDepartmentService _departmentService;
public CompanySummaryViewComponent(IDepartmentService departmentService)
{
this._departmentService = departmentService;
}
#endregion
#region 必须实现
public async Task<IViewComponentResult> InvokeAsync()
{
var summary = await this._departmentService.GetCompanySummary();
return View(summary);
}
#endregion
}
在 Views/Shared 下新建 Components
文件夹
在 Views/Shared/Components 下新建 CompanySummary
文件夹
在 Views/Shared/Components/CompanySummary 下新建 Razor View ,命名 Default
@model My_ASP_NET_Core_Program.Models.CompanySummary
<div class="small">
<div class="row h3">Company Summary</div>
<div class="row">
<div class="col-md-8">员工总数:</div>
<div class="col-md-4">@Model.EmployeeCount</div>
</div>
<div class="row">
<div class="col-md-8">部门平均人数:</div>
<div class="col-md-4">@Model.AverageDepartmentEmployeeCount</div>
</div>
</div>
如何调用 View Component
修改 Views/Department/index.cshtml
@using My_ASP_NET_Core_Program.Models
@model IEnumerable<Department>
<div class="row">
<div class="col-md-10 offset-md-2">
<table class="table">
<tr>
<th>Name</th>
<th>Location</th>
<th>Employee</th>
<th>操作</th>
</tr>
@Html.DisplayForModel()
</table>
</div>
</div>
<div class="row">
@* InvokeAsync() 是异步方法需要 await *@
<div class="col-md-2">
@await Component.InvokeAsync("CompanySummary")
</div>
<div class="col-md-4">
<a asp-action="Add">Add</a>
</div>
</div>
效果图
调用过程:
- 主页中
Component.InvokeAsync()
Component.InvokeAsync()
去调用 Shared/CompanySummary/Default.cshtml- Default.cshtml 去调用 ViewComponents/CompanySummaryViewComponent 的
InvokeAsync()
方法
再添加需求,我们希望每个页面都显示不同的标题
思路:调用 Component 时传入参数,加入 ViewBag
CompanySummaryComponent.cs
public class CompanySummaryViewComponent : ViewComponent
{
#region 依赖注入
private readonly IDepartmentService _departmentService;
public CompanySummaryViewComponent(IDepartmentService departmentService)
{
this._departmentService = departmentService;
}
#endregion
#region 必须实现
public async Task<IViewComponentResult> InvokeAsync(string title)
{
ViewBag.Title = title;
var summary = await this._departmentService.GetCompanySummary();
return View(summary);
}
#endregion
}
Views/Shared/Components/CompanySummary/Default.cshtml
@model My_ASP_NET_Core_Program.Models.CompanySummary
<div class="small">
<div class="row h3">@ViewBag.Title</div>
<div class="row">
<div class="col-md-8">员工总数:</div>
<div class="col-md-4">@Model.EmployeeCount</div>
</div>
<div class="row">
<div class="col-md-8">部门平均人数:</div>
<div class="col-md-4">@Model.AverageDepartmentEmployeeCount</div>
</div>
</div>
Views/Department/index.cshtml
@using My_ASP_NET_Core_Program.Models
@model IEnumerable<Department>
<div class="row">
<div class="col-md-10 offset-md-2">
<table class="table">
<tr>
<th>Name</th>
<th>Location</th>
<th>Employee</th>
<th>操作</th>
</tr>
@Html.DisplayForModel()
</table>
</div>
</div>
<div class="row">
@* InvokeAsync() 是异步方法需要 await *@
<div class="col-md-2">
@await Component.InvokeAsync("CompanySummary", new { title = "部门列表页的汇总" })
</div>
<div class="col-md-4">
<a asp-action="Add">Add</a>
</div>
</div>
效果图
补充
另外一种引用 View Component 方法
添加到@await Component.InvokeAsync("CompanySummary", new { title = "部门列表页的汇总" })
底下
是根据命名引用 View Component ,不过要注意,这里的命名规范改变了
<vc:company-summary title="部门列表的汇总2"></vc:company-summary>
Views/_ViewImports.cshtml ,添加 TagHelper
@addTagHelper "*,Microsoft.AspNetCore.Mvc.TagHelpers"
@addTagHelper "*,My_ASP_NET_Core_Program"
效果图
ASP.NET Core 3.x 入门(三)View Component 结束
自此,MVC 的例子就完了
这是完整的项目结构图