在ASP.NET MVC 6中,view components (VCs) 功能類似于虛拟視圖,但是功能更加強大。 VCs兼顧了視圖和控制器的優點,你可以把VCs 看作一個Mini 控制器。
在ASP.NET MVC 6中,view components (VCs) 功能類似于虛拟視圖,但是功能更加強大。 VCs兼顧了視圖和控制器的優點,你可以把VCs 看作一個Mini 控制器。它負責控制應用中的某一功能子產品,例如:
- 動态導航菜單
- 标簽雲
- 登入面闆
- 購物車
- 最近文章
- 部落格側邊欄
假如使用VC 建立了登入面闆,可以在很多場景中調用,例如:
- 使用者沒有登入
- 使用者已登入,需要退出使用其他帳号登入或者管理其他帳号。
- 如果目前登入角色為管理者,渲染管理者登入面闆
你可以根據使用者的需求擷取資料進行渲染。添加VC到需要該視圖控件的頁面。
VC 包含兩部分,類 (一般繼承于ViewComponent) 和調用VC類中方法的Razor 視圖。類似于ASP.NET 控制器, VC 可以作為POCO使用,但是更多使用者傾向于使用從 VewComponent中繼承而來的方法和屬性。
VC的建立方式有:
- 繼承ViewComponent.
- 擁有 [ViewComponent] 屬性,或者從擁有 [ViewComponent]屬性派生的類。
- 建立名稱已ViewComponent為字尾的類。
和controllers相同,VCs 必須是公開、非嵌套和非抽象的類。
添加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);
}
}
}
代碼注釋:
· 因為PriorityListViewComponent 類繼承于ViewComponent,運作時将通過字元串"PriorityList" 從View中引用該類。在後續章節将會進行詳細闡述。
· [ViewComponent] 屬性用于設定引用VC的别名,例如,建立名稱為XYZ的類,我們可以通過以下代碼設定其引用别名:
[ViewComponent(Name = "PriorityList")]
public class XYZ : ViewComponent
· 元件使用構造注入器使資料内容生效,類似于 Todo 控制器的功能。
· 調用View中的公開方法,可以傳遞任意數量的參數。在異步版本中, InvokeAsync是可用的。在後續章節中我們将提及InvokeAsync 和多參數的使用方法。在之前的代碼中,公開方法的傳回值為代辦事項(ToDoItems),優先級不低于maxPriority。
添加視圖控件
1. 在Views\Todo 檔案夾下建立Components檔案夾,注意這個檔案夾需要命名為Components。
2. 在Views\Todo\Components 檔案夾下建立PriorityList 檔案夾。檔案夾名稱必須和view component 類名稱一緻。或者類名去除字尾名稱(如果在建立類時遵循慣例使用ViewComponent 作為字尾)。如果使用了ViewComponent屬性。
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>
Razor 視圖包含并且顯示了 TodoItems。如果 VC 調用方法沒有傳遞視圖的名稱 (如例子中所示),那麼預設情況下則調用視圖名稱對于方法。在後續的文章中,将闡述如何傳遞視圖名稱。
在views\todo\index.cshtml 視圖底部添加包含有調用PriorityListViewComponent的div:
@model IEnumerable<TodoList.Models.TodoItem>
<h3>Priority Items</h3>
<ul>
@foreach (var todo in Model)
{
<li>@todo.Title</li>
}
</ul>
标記 @await Component.InvokeAsync() 表示該文法用于調用VC。第一個參數是我們要調用的元件名稱。其餘參數參數傳遞給該VC。在這個例子中,我們傳遞“1”作為過濾的優先級。InvokeAsync 方法可以包含任意數量的參數。
以下圖檔顯示了優先級清單:
@{
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>
注意: VC通常被添加到 Views\Shared 檔案夾下,因為它并不僅僅是controller。
添加InvokeAsync 到優先級元件
通過以下代碼更新PriorityListViewComponent類:
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 方法,使用更加強大的asynchronous方法替代。
修改 VC 視圖顯示優先級資訊:
@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>
以下圖檔展示了PriorityListViewComponent類和Index視圖的修改效果:
指定視圖名稱
一些複雜的VC在某些情況下也許需要去指定特定的視圖,以下代碼是通過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\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 檔案:
重新整理頁面檢視更改效果。
在進行開發時,使用 view components 可以更好的檢視頁面效果。如果再借助一些開發工具,還可以大大提高開發效率。ComponentOne Studio for ASP.NET 是ASP.NET平台上的一整套完備的開發工具包,包含的Web窗體控件、MVC scaffolding模闆以及HTML5/JavaScript頁面元件,僅通過幾行代碼就可以在系統中實作豐富的功能。
在MVC6中,更改controller(或其他任何代碼)時,不需要重新編譯或重新運作應用,僅需要儲存代碼并且重新整理頁面即可。
以上即為今天希望和大家分享的view components知識,下一篇文章我們将介紹以下兩部分内容:
- 向視圖中添加服務方法。
- 釋出應用到公有雲方法。
敬請期待。
原文連結:http://www.asp.net/vnext/overview/aspnet-vnext/vc
本文是由葡萄城技術開發團隊釋出,轉載請注明出處:葡萄城官網