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

目录

ASP.NET Core 3.x 入门(一)创建项目 和 部署

ASP.NET Core 3.x 入门(二)建立 Controller ,使用 Tag Helper

ASP.NET Core 3.x 入门(三)View Component

ASP.NET Core 3.x 入门(四)Razor Page

ASP.NET Core 3.x 入门(五)SignalR

ASP.NET Core 3.x 入门(六)Blazor

ASP.NET Core 3.x 入门(七)Web API

ASP.NET Core 3.x 入门(八)gRPC - Protocol Buffer

ASP.NET Core 3.x 入门(九)gRPC in ASP.NET Core 3.x

小例子

在 Index 主页添加一个统计信息

  1. 为什么 Partial View 不行?
    因为没法添加业务逻辑

  2. 如果在 Controller 里面写呢?
    那就无法到处复用

  3. Child Action 呢?
    开销太大,它也需要走完整个 Controller 的生命周期

  4. 就像 Partial View ,但是还带有一个迷你的 Controller ,在这里面也可以写业务逻辑

  5. 可以使用 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>

效果图

调用过程:

  1. 主页中 Component.InvokeAsync()
  2. Component.InvokeAsync() 去调用 Shared/CompanySummary/Default.cshtml
  3. 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 的例子就完了
这是完整的项目结构图

posted @ 2021-05-13 20:04  .NET好耶  阅读(238)  评论(0编辑  收藏  举报