ASP.NET Razor Pages を最初から(7)
はじめに
部分ビューの使用方法はわかったが、ビュー自体にロジックを持たせることができない。
部分ビューにロジックを持たせ単独のパーツとして使用することができるビューコンポーネント
の作成・使用方法を確認する。
ビューファイルを作成する
ビューコンポーネントは、ロジック部分を持つ*.cs
ファイルとビュー部分の*.cshtml
で構成される。
まずは、ビューファイルの配置場所を確認する。
ビューファイルの配置場所
- /Views/{コントローラー名}/Components/{ビュー コンポーネント名}/{ビュー名}
- /Views/Shared/Components/{ビュー コンポーネント名}/{ビュー名}
- /Pages/Shared/Components/{ビュー コンポーネント名}/{ビュー名}
ビューコンポーネント自体が、ASP.NET MVCの時代からある機能のため、Viewsフォルダから検索されるようになっているが、RazorPagesを使う場合はPages/Shared/Components
に配置することになる。
既定のビュー名がDefault.cshtml
になっている。
PriorityList
ビューコンポーネントを作る場合、
Pages/Shared/Components/PriorityList/Default.cshtml
ファイルを作成すればよい。
@{}
<div>
<p>This is PriorityList ViewComponents</p>
</div>
ビューコンポーネントのロジックファイルを作成する
ビュークラスファイル
ファイル自体は、通常のC#クラスファイルだがファイル名はビューに合わせる必要がある。
今回作成しているのはPriorityList
なのでPriorityListViewComponent.cs
とする。
配置場所
ロジックを持つ*.cs
ファイルはどこにでも配置できるようだが
オフィシャルに倣い、プロジェクトのトップにViewComponents
フォルダを作成し、そこに配置していく。
最小のViewComponetクラス
using Microsoft.AspNetCore.Mvc;
namespace ZennSample.ViewComponents;
public class PriorityListViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync()
{
return View();
}
}
ViewComponent
を継承して、Task<IViewComponentResult>
を返す、InvokeAsync
メソッドを実装して、View()を返す。
基本的にはこれだけでビューコンポーネントが完成する。
ビューコンポーネントを使用する
Hoge.cshtml
から、PriorityList
ビューコンポーネントを呼び出してみる。
@page
@model ZennSample.Pages.HogeModel
@{
ViewData["Title"] = "Hoge Title";
}
<div>
<h1>Hoge見出し</h1>
</div>
<partial name="Partial/_HogePartial" for="Product"/>
@await Component.InvokeAsync("PriorityList") @* ここでよびだし *@
タグヘルパーでの呼び出し方法もあるが、ビューコンポーネントに関しては@await Component.InvokeAsync
で呼び出したほうが分かりやすい。
タグヘルパーでの呼び出し
<vc:[view-component-name]
parameter1="parameter1 value"
parameter2="parameter2 value">
</vc:[view-component-name]>
ビューコンポーネントクラスからビューファイルにデータを渡す
ただのHTMLを表示するだけだと部分ビューと変わらないので、作成したPriorityListViewComponent
からDefault.cshtml
にデータを渡して使用する。
using Microsoft.AspNetCore.Mvc;
using ZennSample.Models;
namespace ZennSample.ViewComponents;
public class PriorityListViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync()
{
var p= new Product
{
Number = 2,
Name = "Test ViewComponent",
Description = "これはビューコンポーネントのテストです"
};
return View(p);
}
}
@model ZennSample.Models.Product;
@{}
<div>
<p>This is PriorityList ViewComponents</p>
<ul>
<li>@Model.Number</li>
<li>@Model.Name</li>
<li>@Model.Description</li>
</ul>
</div>
コツを掴めてきたのか、問題なく成功した。
ビューコンポーネントに呼び出し時に値を渡す
データベースに接続して何かデータを取り出す仕組みにする場合
呼び出すPageによって特定の条件を付与したいという事はよくありそうな要件だと思う。
PriorityListにint型とstring型の引数を渡して、ProductのNumberとNameに設定を行ってみる。
パラメータを渡す際には、ViewComponentのInvokeAsyncメソッドに引数を設定する。
public class PriorityListViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(int number=1, string name="Default Name")
{
var p= new Product
{
Number = number,
Name = name,
Description = "これはビューコンポーネントのテストです"
};
return View(p);
}
}
デフォルト値は必須ではないが、引数無しでも呼び出せるように設定しておく。
@page
@model ZennSample.Pages.HogeModel
@await Component.InvokeAsync("PriorityList", new{number=100, name="ビュー引数"})
InvokeAsyncの第2引数に、匿名型の形で引数を渡す。
引数として与えた値が表示されている事が確認できた。
Discussion