ASP.NET Core MVC - ビューコンポーネントの呼び出し方色々
ASP.NET Core MVCのビューコンポーネントを試してみました。
ビューコンポーネントは従来のASP.NET MVCにあったチャイルドアクション(子アクション、ビューからRenderActionで呼び出していたあれ)の代わりになる機能ですね。呼び出し方が色々あるようなので、ちょっと書き残しておきます。
ビューコンポーネント名を指定する
上記ドキュメントにありますが、ビューコンポーネント名を指定して呼び出す方法があります。試してみましょう。
次のようなビューコンポーネントクラスを用意します。csファイルはプロジェクト直下に「ViewComponents」フォルダを作ってそこに入れるといいのかな?
// 適当なビューコンポーネント public class Sample1ViewComponent : ViewComponent { public async Task<IViewComponentResult> InvokeAsync(int no, string name) { // 何か重たい処理があるとして await Task.Delay(0); // ViewBagも使える(それかViewModelを作るか) ViewBag.No = no; ViewBag.Name = name; return View(); } }
続いてビューコンポーネントの呼び出し側。Component.InvokeAsyncメソッドの1つ目の引数にビューコンポーネント名を、2つ目の引数にはSample1ViewComponent.InvokeAsyncメソッドの引数を匿名オブジェクトで指定します。
@await Component.InvokeAsync("Sample1", new { no = 1, name = "Sample1 string" })
型を指定する
typeof演算子で型を指定して呼び出す方法もあります。
@await Component.InvokeAsync(typeof(Sample1ViewComponent), new { no = 2, name = "Sample1 typeof" })
ジェネリック メソッドを使う
ジェネリック(ジェネリクス?)メソッドが用意されているので、次のような呼び出し方もできます。ただ丸括弧"()"を使う必要があってちょっとだけ残念。ちょいちょい括弧を忘れてコンパイラさんに怒られそう。
@(await Component.InvokeAsync<Sample1ViewComponent>(new { no = 3, name = "Sample1 generics" }))
引数にクラスを使う
ビューコンポーネントを呼び出す引数は、匿名オブジェクトではなく具体的なクラスでも問題なさそうです。
引数が多いという体で引数をクラスにまとめます。
// 適当なビューコンポーネントその2 public class Sample2ViewComponent : ViewComponent { // ビューコンポーネントの呼び出しパラメータクラス // インナークラスにする必要はないけど public class Param { public int No { get; set; } public string Name { get; set; } } // 引数にParamクラスを受け取る public async Task<IViewComponentResult> InvokeAsync(Param param) { // 何か重たい処理があるとして await Task.Delay(0); ViewBag.No = param.No; ViewBag.Name = param.Name; return View(); } }
呼び出し側もわかりやすいのでこの方法もありかなと思います。
@await Component.InvokeAsync(typeof(Sample2ViewComponent), new Sample2ViewComponent.Param { No = 4, Name = "Sample2" })
コントローラのアクションから呼び出す
ちょっと話は変わりますが、ビューコンポーネントはビューだけでなくコントローラのアクションメソッドでも呼び出せます。Ajaxでも使いたいときですかね。
// ビューコンポーネントを返すアクション public IActionResult Sample1() { return ViewComponent(typeof(Sample1ViewComponent), new { no = 5, name = "Sample1 controller" }); }
こんなところかなと。