Razorコンポーネントのビュー・ロジックの分割
はじめに
Razorコンポーネントでは、@code ブロック内で定義したメンバーとHTML要素をバインドして処理を記述できる。
しかし可読性等の観点より、Razorコンポーネントに処理をまとめるのではなく、ビュー・ロジックは分割させたい場合がある。その記法を試していく。
以下プロパティ・メソッドを持つRazorコンポーネントの、ビュー・ロジックを分割する。
1. コンポーネントのパラメーター([Parameter] 属性)
2. ライフサイクル用関数
3. ユーザー関数(Javascript呼び出し)
@inject IJSRuntime JS @foreach (var exe in Executed) { <p>@exe</p> } @code { // 実行済リスト(ページに一覧表示) private List<string> Executed { get; set; } = new(); // パラメーター private string _param = string.Empty; [Parameter] public string Param { get { return _param; } set { Executed.Add(value); _param = value; } } // ▽ライフサイクル // 初期化 protected override async Task OnInitializedAsync() { Executed.Add("OnInitializedAsync"); } // レンダリング後 protected override async Task OnAfterRenderAsync(bool firstRendeer) { if (firstRendeer) { ExceRazor(); await ExceJSAsync(); // 再レンダリング await InvokeAsync(() => StateHasChanged()); return; } } // △ライフサイクル // ユーザー関数 private void ExceRazor() { Executed.Add("ExceRazor"); } // ユーザー関数(Javascript呼び出し) private async Task ExceJSAsync() { Executed.Add(await JS.InvokeAsync<string>("ExceJS")); } }
@page "/" <PageTitle>Index</PageTitle> <TestComponent Param="Param" />
Index.razorに上記のコンポーネントを含めると、1~3のプロパティ・メソッドが呼ばれている事が確認できる。
ビュー・ロジックを分割後に同様の動作が再現できれば、成功とする。
部分クラス
Blazorでは部分クラスがサポートされているため、
コンポーネント (.razor) と紐づく分離コード ファイル (.cs) に部分クラスを定義できる。
@foreach (var exe in Executed) { <p>@exe</p> }
using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; namespace Blazor_CodeBehind.Pages { public partial class TestComponentPartial { // 実行済リスト(ページに一覧表示) private List<string> Executed { get; set; } = new(); // JSランタイムのインスタンス [Inject] private IJSRuntime JS { get; set; } // パラメーター private string _param = string.Empty; [Parameter] public string Param { get { return _param; } set { Executed.Add(value); _param = value; } } // ▽ライフサイクル // 初期化 protected override async Task OnInitializedAsync() { Executed.Add("OnInitializedAsync"); } // レンダリング後 protected override async Task OnAfterRenderAsync(bool firstRendeer) { if (firstRendeer) { ExceRazor(); await ExceJSAsync(); // 再レンダリング await InvokeAsync(() => StateHasChanged()); return; } } // △ライフサイクル // ユーザー関数 private void ExceRazor() { Executed.Add("ExceRazor"); } // ユーザー関数(Javascript呼び出し) private async Task ExceJSAsync() { Executed.Add(await JS.InvokeAsync<string>("ExceJS")); } } }
1~3のプロパティ・メソッドが呼ばれている事が確認でき、ビュー・ロジックが分割できている。
部分クラス移行時の変更箇所
@foreach (var exe in Executed) { <p>@exe</p> }
public partial class TestComponentPartial
learn.microsoft.com
// JSランタイムのインスタンス [Inject] private IJSRuntime JS { get; set; }
基本クラス
@inherits ディレクティブでコンポーネントの基本クラスを指定し、メソッド・プロパティを利用できる。
@using Blazor_CodeBehind.Data; @inherits TestComponentBaseClass @foreach (var exe in Executed) { <p>@exe</p> }
using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; namespace Blazor_CodeBehind.Data { public partial class TestComponentBaseClass : ComponentBase { // アクセス権を変更 // 実行済リスト(ページに一覧表示) protected List<string> Executed { get; set; } = new(); // JSランタイムのインスタンス [Inject] public IJSRuntime JS { get; set; } // パラメーター private string _param = string.Empty; [Parameter] public string Param { get { return _param; } set { Executed.Add(value); _param = value; } } // ▽ライフサイクル // 初期化 protected override async Task OnInitializedAsync() { Executed.Add("OnInitializedAsync"); } // レンダリング後 protected override async Task OnAfterRenderAsync(bool firstRendeer) { if (firstRendeer) { ExceRazor(); await ExceJSAsync(); // 再レンダリング await InvokeAsync(() => StateHasChanged()); return; } } // △ライフサイクル // ユーザー関数 private void ExceRazor() { Executed.Add("ExceRazor"); } // ユーザー関数(Javascript呼び出し) private async Task ExceJSAsync() { Executed.Add(await JS.InvokeAsync<string>("ExceJS")); } } }
1~3のプロパティ・メソッドが呼ばれている事が確認でき、ビュー・ロジックが分割できている。
基本クラス移行時の変更箇所
@using Blazor_CodeBehind.Data; @inherits TestComponentBaseClass @foreach (var exe in Executed) { <p>@exe</p> }
@codeの記載は全て基本クラスに移行する。
public class TestComponentBaseClass : ComponentBase
ライフサイクル関数はComponentBaseで定義されているため、基本クラスでComponentBaseを継承する。
// アクセス権を変更 // 実行済リスト(ページに一覧表示) protected List<string> Executed { get; set; } = new();
部分クラスとは異なり、コンポーネントより呼び出すプロパティがprivateではいけない。
備考
基本クラスの複数指定は不可能だった。
まとめ
Razorコンポーネントの以下プロパティ・メソッドも、部分クラス・基本クラスに分割することが可能だった。
1. コンポーネントのパラメーター([Parameter] 属性)
2. ライフサイクル用関数
3. ユーザー関数(Javascript呼び出し)