Lightning Blog
Blazor記事イメージ画像

【Blazor】 動的なコンポーネントの使い方

更新日:2023/08/30

条件分岐によって、表示するコンポーネントを切り替えたい場合はif文など使用して切り替えることができますが、コードが冗長になってしまいます。 動的なコンポーネントを用意することで、よりシンプルに書くことができるようになります。

    目次

  • 動的なコンポーネントを使ってみる
  • 動的コンポーネントにパラメータを渡す

動的なコンポーネントを使ってみる

セクション画像

実際に動的なコンポーネント(DynamicComponent)を使用した例を見ていきましょう。 ドロップダウンのコンポーネントから、果物を選択すると、それに応じたコンポーネントに切り替わるような仕様にしていきます。 まずそれぞれの果物のコンポーネントを作成していきます。


<h1>Apple</h1>

<h1>Orange</h1>

<h1>Banana</h1>

次にドロップダウンで動的にコンポーネントを切り替えるコードを書いていきます。 既存のIndex.razorのコードを次のように書き換えてください。


@page "/"

@using Blazor_DynamicComponent.Components;
@using Blazor_DynamicComponent.Model;

<p>
    <label>
        果物を選択してください。
    </label>
    <select @onchange="OnDropdownChange">
        <option value="">未選択</option>
        <option value="@nameof(Apple)">リンゴ</option>
        <option value="@nameof(Orange)">オレンジ</option>
        <option value="@nameof(Banana)">バナナ</option>
    </select>
</p>

@if (selectedType is not null)
{
    <DynamicComponent Type="@selectedType" />
}

@code{

    /// <summary>
    /// 選択されているコンポーネントのタイプ
    /// </summary>
    private Type? selectedType;

    /// <summary>
    /// ドロップダウン変更イベント
    /// </summary>
    /// <param name="e"></param>
    private void OnDropdownChange(ChangeEventArgs e)
    {
        selectedType = e.Value?.ToString()?.Length > 0 ?
            Type.GetType($"Blazor_DynamicComponent.Components.{e.Value}") : null;
    }

}

ドロップダウンの変更イベントで、DynamicComponentに渡すコンポーネントのタイプのパラメータを切り替えるようにしています。 OnDropdownChangeメソッド内のBlazor_DynamicComponent.Components.の部分は、果物のコンポーネントが属する名前空間に書き換えてください。

実行して確認してみます。問題なく動作することを確認してください。

実行結果
実行結果

動的コンポーネントにパラメータを渡す

セクション画像

動的コンポーネントは、通常のコンポーネントと同様にパラメータを設定することもできます。 現在の果物コンポーネントでは、値を受け取るパラメータが存在しないためそれぞれ追加していきます。


<h1>Apple</h1>
<label>@Impressions</label>

@code {

    /// <summary>
    /// 感想文
    /// </summary>
    [Parameter]
    public string Impressions { get; set; }

}

<h1>Orange</h1>
<label>@Impressions</label>

@code {

    /// <summary>
    /// 感想文
    /// </summary>
    [Parameter]
    public string Impressions { get; set; }

}

<h1>Banana</h1>
<label>@Impressions</label>

@code {

    /// <summary>
    /// 感想文
    /// </summary>
    [Parameter]
    public string Impressions { get; set; }

}

果物コンポーネントには、果物を食べた感想を文字列として、パラメータ指定できるようにしてみました。 ドロップダウンの選択肢の値(<option>の値)と動的コンポーネントに渡すパラメータを紐づけるために、新たにComponentMetadataクラスを作成します。


namespace Blazor_DynamicComponent.Model
{
    /// <summary>
    /// コンポーネントの情報クラス
    /// </summary>
    public class ComponentMetadata
    {
        /// <summary>
        /// UIに表示する名前
        /// </summary>
        public string? Name { get; set; }

        /// <summary>
        /// コンポーネントに渡すパラメータ
        /// </summary>
        public Dictionary<string, object> Parameters { get; set; } =
        new Dictionary<string, object>();
    }
}

ドロップダウンを利用するページを変更していきます。以下のように書き換えて下さい。


@page "/"

@using Blazor_DynamicComponent.Components;
@using Blazor_DynamicComponent.Model;

<p>
    <label>
        果物を選択してください。
    </label>
    <select @onchange="OnDropdownChange">
        <option value="">未選択</option>
        @foreach (var c in components)
        {
            <option value="@c.Key">@c.Value.Name</option>
        }
    </select>
</p>

@if (selectedType is not null)
{
    <DynamicComponent Type="@selectedType" Parameters="@components[selectedType.Name].Parameters" />
}

@code {

    /// <summary>
    /// 選択されているコンポーネントのタイプ
    /// </summary>
    private Type? selectedType;

    /// <summary>
    /// コンポーネント名をキーとして、
    /// ドロップダウンの選択肢名とコンポーネントに渡すパラメータを検索する辞書
    /// </summary>
    private Dictionary<string, ComponentMetadata> components = new()
    {
        {
            nameof(Apple),
            new ComponentMetadata
            {
                Name = "リンゴ",
                Parameters = new() { { "Impressions", "リンゴは美味しい" } }
            }
        },
        {
            nameof(Orange),
            new ComponentMetadata
            {
                Name = "ミカン",
                Parameters = new() { { "Impressions", "ミカンは美味しい" } }
            }
        },
        {
            nameof(Banana),
            new ComponentMetadata
            {
                Name = "バナナ",
                Parameters = new() { { "Impressions", "バナナは美味しい" } }
            }
        }
    };

    /// <summary>
    /// ドロップダウン変更イベント
    /// </summary>
    /// <param name="e"></param>
    private void OnDropdownChange(ChangeEventArgs e)
    {
        selectedType = e.Value?.ToString()?.Length > 0 ?
            Type.GetType($"Blazor_DynamicComponent.Components.{e.Value}") : null;
    }

}

ドロップダウン変更イベントで選択されているコンポーネントのタイプ(selectedType)を変更し、 そのタイプ名からコンポーネントに渡すパラメータを指定するようになっています。

ドロップダウンを変更して、指定した果物名とパラメータが表示されることを確認してください。

実行結果
実行結果

ブログ内の記事で書かれているサンプルコードは、GitHubから確認する事ができます。 是非参考にしてみてください。

この本では、Blazorの基本から高度なテクニックまで、実際のプロジェクトに役立つ知識を網羅しています。 初心者から経験者まで、Blazorを扱うすべての開発者にとっての必読書です。 この記事の執筆者も参考にした「Blazor入門」で、あなたのBlazorスキルを飛躍的に向上させませんか?

合わせて読みたい

カード画像
RenderFragmemtの使い方

Blazorでのページ作成時に共通レイアウトの再利用性を高めるため、RenderFragmentを利用する方法を紹介。RenderFragmentを使ったコンポーネントを作成し、その中でChildContentを通してページ固有の内容を指定。これにより、類似のレイアウトを持つページでもコードの重複を防ぎ効率的な実装が可能になる。

更新日:2023/07/09

カード画像
appsettings.jsonの使い方

Blazor Serverでのappsettings.jsonの使い方を解説します。開発環境や運用環境に応じた設定の使い分け方法も紹介し、appsettings.jsonから設定値を読み込む手順を具体的に説明します。

更新日:2024/06/12

An error has occurred. This application may no longer respond until reloaded. Reload 🗙