介绍视图组件

视图组件是 ASP.NET Core MVC 中的新特性,与局部视图相似,但是它们更加的强大。视图组件不使用模型绑定,只取决于调用它时所提供的数据。视图组件有以下特点:

  • 渲染一个块,而不是整个响应
  • 在控制器和视图之间同样包含了关注点分离和可测试性带来的好处
  • 可以拥有参数和业务逻辑
  • 通常从布局页调用

视图组件可以用在任何需要重复逻辑且对局部视图来说过于复杂的情况,比如:

  • 动态导航菜单
  • 标签云 (需要从数据库查询时)
  • 登录面板
  • 购物车
  • 最近发表的文章
  • 一个典型博客的侧边栏内容
  • 会在所有页面渲染的登录面板,根据用户登录状态显示登录或者注销

一个 视图组件 包含两个部分,类(通常派生自 ViewComponent )和它返回的结果(通常是一个视图)。类似控制器,视图组件可以是 POCO 类型,但是大部分开发者想要使用派生自 ViewComponent 的方法和属性。

 

创建视图组件

这个章节包含创建视图组件的高级需求。在稍后的文章中,我们将详细地检查每一个步骤,并创建一个视图组件。

 

视图组件类

一个视图组件类可以由以下任何一个方式创建:

  • 派生自 ViewComponent
  • 使用 [ViewComponent] 特性装饰一个类,或者这个类的派生类。
  • 创建一个类,并以 ViewComponent 作为后缀。

如同控制器一样,视图组件必须是公开的,非嵌套的,以及非抽象的类。视图组件名称是类名并去掉“ViewComponent”后缀。也可以通过 ViewComponentAttribute.Name 属性进行明确的指定。

一个视图组件类:

  • 完全支持构造函数依赖注入
  • 不参与控制器生命周期,意味着你不能在视图组件中使用过滤器
 

视图组件方法

视图组件在 InvokeAsync 方法中中定义逻辑,并返回 [IViewComponentResultIViewComponentResult。参数直接来自视图组件的调用,而不是来自模型绑定。视图组件从来不直接处理请求。通常视图组件初始化模型并通过调用 View方法传递它到视图。总之,视图组件方法有以下特点:

  • 定义一个 InvokeAsync 方法并返回 IViewComponentResult
  • 通常初始化模型并通过调用ViewComponent View方法传递它到视图
  • 参数来自调用方法,而不是 HTTP,没有模型绑定
  • 不可直接作为 HTTP 终结点,它们从你的代码中调用(通常在视图中)。视图组件从不处理请求
  • 重载的签名,而不是当前 HTTP 请求中的任何细节
 

视图搜索路径

运行时对视图的搜索路径如下:

  • Views/<controller_name>/Components/<view_component_name>/<view_name>
  • Views/Shared/Components/<view_component_name>/<view_name>

视图组件默认的视图名是 Default,意味着通常你的视图文件会命名为 Default.cshtml。当你创建视图组件结果或者调用 View 方法的时候,你可以指定不同的视图名。

我们建议你命名视图文件为 Default.cshtml 并且使用 Views/Shared/Components/<view_component_name>/<view_name> 路径。在这个例子中使用的 PriorityList 视图组件使用了 Views/Shared/Components/PriorityList/Default.cshtml 这个路径。

 

调用视图组件

要使用视图组件,从视图中调用 @Component.InvokeAsync("视图组件名", <匿名类型参数>)。参数将传递给 InvokeAsync 方法。在文章中开发的 PriorityList 视图组件被 Views/Todo/Index.cshtml 视图文件调用。在下面,使用了两个参数调用 InvokeAsync 方法:

@await Component.InvokeAsync("PriorityList", new { maxPriority = 2, isDone = false })
 

从控制器直接调用视图组件

视图组件通常从视图中调用,但是你也可以从控制器方法中直接调用。当视图组件没有像控制器一样定义终结点时,你可以简单实现一个控制器的 Action ,并使用一个 ViewComponentResult作为返回内容。

在这例子中,视图组件通过控制器直接调用:

 public IActionResult IndexVC()
{
return ViewComponent("PriorityList", new { maxPriority = 3, isDone = false });
}
 

演练:创建一个简单的视图组件

生成并测试启动代码。这是一个简单的项目,使用一个 Todo 控制器来显示 Todo 项列表。

添加一个视图组件类

创建一个 ViewComponents 文件夹并添加下面的 PriorityListViewComponent 类。

using Microsoft.AspNet.Mvc;
using Microsoft.Data.Entity;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ViewComponentSample.Models; namespace ViewComponentSample.ViewComponents
{
public class PriorityListViewComponent : ViewComponent
{
private readonly ToDoContext db; public PriorityListViewComponent(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();
}
}
}

代码注释:

  • 视图组件类可以被放在项目中 任何 文件夹内。
  • 因为类命名为 PriorityListViewComponent,以 ViewComponent 作为后缀结束,在运行时会从视图中使用 "PriorityList" 字符串来引用组件类。我会在后面详细解释。
  • [ViewComponent] 特性可以改变被用来引用视图组件的名字。比如,我们可以命名类为 XYZ,然后应用 ViewComponent 特性:
[ViewComponent(Name = "PriorityList")]
public class XYZ : ViewComponent
  • 上面的 [ViewComponent] 特性告知视图组件选择器在寻找与组件相关的视图时使用名字 PriorityList,并且在从视图中引用组件类时使用 "PriorityList" 字符串。我会在后面详细解释。
  • 组件使用依赖注入使得数据上下文可用。
  • InvokeAsync 暴露一个可以在视图中调用的方法,并且它可以接受任意数量的参数。
  • InvokeAsync 方法返回没有完成并优先级小于等于 maxPriority 的 ToDo 项的集合。
 

创建视图组件 Razor 视图

  1. 创建 Views/Shared/Components 文件夹。这个文件夹 必须 命名为 Components。
  2. 创建 Views/Shared/Components/PriorityList 文件夹。这个文件夹必须和视图组件类名字匹配,或者是类名去掉后缀(如果我们遵循了约定并且使用 ViewComponent 作为类名后缀)。如果你使用 ViewComponent 特性,类名需要匹配特性中指定的名字。
  3. 创建一个 Views/Shared/Components/PriorityList/Default.cshtml Razor 视图。
@model IEnumerable<ViewComponentSample.Models.TodoItem>

<h3>Priority Items</h3>
<ul>
@foreach (var todo in Model)
{
<li>@todo.Name</li>
}
</ul>

Razor 视图取一组 TodoItem 并显示它们。如果视图组件的 InvokeAsync 方法没有传递视图名(就像我们例子中),按照约定会使用 Default 作为视图名。在教程的后面部分,我会告诉你如何传递视图的名称。为特定控制器重写默认的样式,添加一个视图到特定控制器的视图文件夹(比如 Views/Todo/Components/PriorityList/Default.cshtml)。

如果视图组件是特定控制器的,你可以添加到特定控制器文件夹(Views/Todo/Components/PriorityList/Default.cshtml)。

  1. 在 Views/Todo/index.cshtml 文件底部添加一个 div 包含调用 PriorityList 组件:
<div >
@await Component.InvokeAsync("PriorityList", new { maxPriority = 2, isDone = false })
</div>

标记 @Component.InvokeAsync 展示了调用视图组件的语法。第一个参数是我们想要调用的组件名。随后的参数传递给组件。InvokeAsync 可以接受任意数量的参数。

下面的图片显示了 Priority 项:

你也可以从控制器直接调用视图组件:

public IActionResult IndexVC()
{
return ViewComponent("PriorityList", new { maxPriority = 3, isDone = false });
}
 

指定视图名

一个复杂的视图组件在某些条件下可能需要指定非默认的视图。下面的代码展示如何从 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 视图来表明正在使用此视图。

@model IEnumerable<ViewComponentSample.Models.TodoItem>

<h2> PVC Named Priority Component View</h2> // 手动高亮
<h4>@ViewBag.PriorityMessage</h4>
<ul>
@foreach (var todo in Model)
{
<li>@todo.Name</li>
}
</ul>

更新 Views/TodoList/Index.cshtml


<div>
@await Component.InvokeAsync("PriorityList", new { maxPriority = 4, isDone = true })
</div>

运行应用程序并验证 PVC 视图。

如果 PVC 视图没有渲染,请验证你是否使用 4 或者更高 priority 参数来调用视图组件。

 

检查视图路径

  1. 改变 priority 参数到 3 或者更低,使得不返回优先级视图。
  2. 暂时重命名 Views/Todo/Components/PriorityList/Default.cshtml 为 Temp.cshtml。
  3. 测试应用程序,你将得到以下错误:

    An unhandled exception occurred while processing the request.

    InvalidOperationException: The view 'Components/PriorityList/Default'
    was not found. The following locations were searched:
    /Views/ToDo/Components/PriorityList/Default.cshtml
    /Views/Shared/Components/PriorityList/Default.cshtml.
    Microsoft.AspNetCore.Mvc.ViewEngines.ViewEngineResult.EnsureSuccessful()

  4. 复制 Views/Shared/Components/PriorityList/Default.cshtml 到 Views/Todo/Components/PriorityList/Default.cshtml。
  5. 添加一些标记到 Todo 视图组件视图来表明视图是来自 Todo 文件夹。
  6. 测试 非共享 组件视图。

 

避免魔法字符串

如果你想编译时安全你可以用类名替换硬编码视图组件名。创建视图组件不以 "ViewComponent" 作为后缀:

using Microsoft.AspNet.Mvc;
using Microsoft.Data.Entity;
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();
}
}
}

添加一个 using 语句到你的 Razor 视图文件并使用 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://www.cnblogs.com/dotNETCoreSG/p/aspnetcore-4_3_9-view-component.html

asp.net core 视图组件(转)的更多相关文章

  1. 笔记: ASP.NET Core视图组件

    视图组件 asp.net core mvc 提供了部分视图的新替代品:视图组件. 视图组件与分布视图的主要区别在于视图组件与控制器不相关.可使用在独立于单个控制器的场景,如:菜单导航.侧边栏.分页栏等 ...

  2. asp.net core 视图组件化

    视图组件可以通过partial view或viewcomponent实现 partialview https://docs.microsoft.com/zh-cn/aspnet/core/mvc/vi ...

  3. asp.net core视图组件(ViewComponent)简单使用

    一.组成: 一个视图组件包括两个部分,派生自ViewComponent的类及其返回结果.类似控制器. 定义一个视图组件,如控制器一样,必须是公开,非嵌套,非抽象的类.一般,视图组件名称为类名去掉&qu ...

  4. Asp.Net core 视图组件ViewComponent

    视图组件 ViewComponent 最近用了一下视图组件,还挺方便的,如果遇到公共的部分,可以抽出来,写成视图组件,方便调用 先上图看一下效果:比如首页的4个画红框的地方是4个模块,有些地方可能要重 ...

  5. [转]asp.net core视图组件(ViewComponent)简单使用

    本文转自:http://www.cnblogs.com/dralee/p/6170496.html 一.组成: 一个视图组件包括两个部分,派生自ViewComponent的类及其返回结果.类似控制器. ...

  6. ASP.NET Core 视图 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 视图 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 视图 花了几章节,终于把 ASP.NET Core MVC 中的 C 控 ...

  7. Asp.Net Core 视图整理(一)

    一.部分视图的使用 注:1.目前在Asp.Net Core2.0中对于部分视图的支持主要使用 Html.Partial()/Html.PartialAsync(); Html.RenderPartia ...

  8. Blazor入门:ASP.NET Core Razor 组件

    目录 关于组件 组件类 静态资产 路由与路由参数 组件参数 请勿创建会写入其自己的组参数属性的组件 子内容 属性展开 任意参数 捕获对组件的引用 在外部调用组件方法以更新状态 使用 @ 键控制是否保留 ...

  9. asp.net core日志组件

    日志介绍 Logging的使用 1. appsettings.json中Logging的介绍 Logging的配置信息是保存在appsettings.json配置文件中的.因为之前介绍配置文件的时候我 ...

随机推荐

  1. Apple macOS 下载汇总

    macOS Big Sur 11,macOS Catalina 10.15,macOS Mojave 10.14,macOS High Sierra 10.13,macOS Sierra 10.12 ...

  2. 游刃于私有网络与公共网络之间的NAT

    网络地址转化技术NAT 1. 应用场景 2. NAT 2.1 静态NAT 2.2 动态NAT 2.3 NAPT 2.4 EASY IP 3. NAT配置 3.1 静态NAT 3.2 动态NAT 3.3 ...

  3. (续篇)Selenium 安装配置以及如何解决('chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/ch)或者(unknown error:cannot find Chrome binary)问题?

    注:本帖针对小小白哦~~(づ ̄3 ̄)づ╭- 接pip安装的帖子,不需要的直接跳过... 首先上图,出现如下的错误,那你可是找到知己了: 或者: 抱歉抱歉,这图截的不太清晰,凑合着用吧,但是也能看出来错 ...

  4. 行人检测与重识别!SOTA算法

    行人检测与重识别!SOTA算法 A Simple Baseline for Multi-Object Tracking, Yifu Zhang, Chunyu Wang, Xinggang Wang, ...

  5. Minecraft类游戏地形生成机制

    目录 前言 生成地形高度 生成生物群落 模拟雨水侵蚀.生成河流(未完) 生成洞穴.裂谷 生成植被 放置树木(Bezier曲线) 生成建筑 生成发展域(元胞自动机模型) 放置建筑(DFS) 连接道路(A ...

  6. 【Android编程】Java利用apktool编写Metasploit恶意后门注入工具

    /声明:本文作者Kali_MG1937 csdn博客id:ALDYS4 QQ:3496925334 未经许可禁止转载!/ 注意,本文为作者从CSDN搬迁至此的文章 注意!此文章虽然 未被 作者标记到 ...

  7. centos7 安装卸载程序rpm使用方法

    1.安装 rpm 包: ➢ 基本语法 rpm -ivh RPM 包全路径名称 2.卸载 rpm 包: ➢ 基本语法 rpm -e RPM 包的名称 ➢ 应用案例 删除 firefox 软件包 rpm ...

  8. NOIP模拟测试8「匹配·回家」

    匹配 哈希能A 水到爆炸 回家 事实上我做过一个原题,甚至比这个回家难的多,而且那个题多组询问必经点 然后我做一组询问就打炸了 大约就是删了很多东西,然后自己想的太简单了 直接统计了割点,懒得打lca ...

  9. 《电容应用分析精粹:从充放电到高速PCB设计》最新勘误表

    最新勘误表百度云盘下载 链接: https://pan.baidu.com/s/18yqwnJrCu9oWvFcPiwRWvA  提取码: x3e3    (本勘误表仅包含错误相关部分,不包含对语句的 ...

  10. 使用echarts时,鼠标首次移入屏幕会闪动,全屏会出现滚动条

    原因: 在echarts图表中出现tooltip时,画布的父标签(即:echarts.init()的标签)的有时宽高都会发生变化,导致相对布局的div可能大小发生变化(画布大小却不变),导致页面闪动. ...