文章出處

在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>

image

注意: 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視圖的修改效果:

image

 

指定視圖名稱

一些復雜的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


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()