目的
Blazor内でコンポーネントを使いまわしたい(モーダルを実装したい)
参考
理想の形
引数で特定のテキストやスタイルに文字列を挿入しながら、
中身のコンテンツはHTMLで書きたい
TestPage.razor
<Component Title="タイトル" Desc="説明が入る">
<p>フォームやらなんやらが入る</p>
</Component>
パラメータによる参照
<Component Title="タイトル" Desc="説明が入る"> // ←これ
</Component>
''コンポーネント パラメーター'' によりデータがコンポーネントに渡されます。これらのパラメーターは、[Parameter] 属性を指定したコンポーネント クラス上で、パブリック C# プロパティを使用して定義されます。 次の例では、組み込みの参照型 (System.String) とユーザー定義の参照型 (PanelBody) がコンポーネント パラメーターとして渡されます。
[Parameter]
をうまく使うといけるらしい。
テスト実装
Component.razor
@code {
[Parameter]
public string Title { get; set; } = "";
[Parameter]
public string Desc {get; set; } = "";
}
Component.razor
<h2>@Title</h2>
<p>@Desc</p>
TestPage.razor
<Component Title="タイトル" Desc="説明が入る" />
出力結果
HTML
<h2>タイトル</h2>
<p>説明が入る</p>
レンダリングフラグメントの活用
<Component Title="タイトル" Desc="説明が入る">
<p>フォームやらなんやらが入る</p> //←これ
</Component>
コンポーネントでは、別のコンポーネントのコンテンツを設定できます。 代入コンポーネントでは、子コンポーネントの開始および終了タグの間にコンテンツを指定します。
Razorマークアップ内の ChildContent の位置は、コンテンツが最終的な HTML 出力にレンダリングされる場所です。
とのこと。
テスト実装
Component.razor
@code{
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
Component.razor
<div class="child">
@ChildContent
</div>
プロパティはChildContent
以外の名前を受け付けていません
(他の名称にするとエラーになります)
TestPage.razor
<Component>
コンテンツが入ります
</Component>
出力結果
HTML
<div class="child">
コンテンツが入ります
</div>
Bootstrapモーダルを再利用可能なコンポーネントにする
パラメータとレンダリングフラグメントを組み合わせて、モーダルを作成してみます。
これでスッキリ。
TestPage.razor(コンポーネント利用側)
<Modal ModalTarget="staticBackdrop" ModalTitle="タイトル" SubmitButtonText="実行" CancelButtonText="キャンセル">
<div class="row mb-3">
<div class="col-3">
<label for="area" class="col-form-label d-flex justify-content-between align-items-center">フォーム:</label>
</div>
<div class="col-6">
<input type="text" name="" id="" class="form-control">
</div>
</div>
</Modal>
Modal.razor
<div class="modal fade" id="@ModalTarget" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content p-3">
<div class="modal-header justify-content-between align-items-start">
<p></p>
<div class="text-center">
<h1 class="modal-title fs-5 text-purple" id="staticBackdropLabel">@ModalTitle</h1>
</div>
<button type="button" class="btn-close m-0 p-0" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="conteiner-fluid">
@ChildContent
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-purple">@SubmitButtonText</button>
<button type="button" class="btn btn-outline-purple" data-bs-dismiss="modal">@CancelButtonText</button>
</div>
</div>
</div>
</div>
Modal.razor
@code {
[Parameter]
public string ModalTarget { get; set; } = "";
[Parameter]
public string ModalTitle { get; set; } = "";
[Parameter]
public string SubmitButtonText { get; set; } = "";
[Parameter]
public string CancelButtonText { get; set; } = "";
[Parameter]
public RenderFragment? ChildContent { get; set; }
}