入門者向け

【Blazor】カスケーディングを使ってパラメーターを渡す方法

cascading-parameter

カスケードとは、もともと「連なった小さな滝」という意味があります。

Blazor では滝が流れるイメージで、上位の階層から下位の階層にパラメーターを渡すことができる仕組みがあります。

これが「カスケーディングパラメーター」です。

これを使うことで、いちいち各画面で別々のインスタンスを生成しなくてもよくなります。

本記事では、カスケーディングを使ってパラメーターを渡す具体的な方法について解説しました。

では、さっそく見ていきましょう。

カスケーディングを使ってパラメーターを渡す方法

先に結論をまとめると、以下のようになります。

カスケーディングの使い方

渡す側
  • CascadingValue のタグを使って定義
  • Value 属性に値を定義
  • 複数渡す場合は Name 属性の定義が必須(ひとつの場合は任意)
受け取る側
  • CascadingParameter の属性をプロパティに付与
  • CascadingValue で定義した Name 属性と一致させる

使い方を試す流れとしては、メッセージクラスを定義して、渡ってきたパラメーターに従って画面にメッセージを表示することを考えました。

ひとつのパラメーターを渡す方法と、複数のパラメーターを渡す方法を見ていきましょう。

ひとつのパラメーターを渡す

まずは Message クラスを定義します。

引数なしの場合は名前が Guest、引数ありの場合は受け取った引数で名前を出すようにしました。

作る場所はどこでもいいですが、Cascade というフォルダの下に作成しました。

Cascade/Message.cs
using System;
namespace BlazorTest.Client.Cascade
{
    public class Message
    {
        private string _name;

        public Message()
        {
            _name = "Guest";
        }

        public Message(string name)
        {
            _name = name;
        }

        public string GetText()
        {
            return $"Hello {_name}!!";
        }
    }
}

 

まず初めに、MainLayout.razor を開き、渡したいパラメーターを変数として定義しましょう。

続いて、@Body を囲うように CascadingValue のタグを追加します。

@Body は各画面を表しているので、CascadingValue のタグ囲うと全画面に対してパラメーターが使えるようになります。

Value の指定は必須で、先ほど定義した変数を渡してあげましょう。

パラメーターがひとつのときは必須ではありませんが、Name 属性もつけておきます。

Name 属性は、パラメーターを受け取る側で指定すると、指定した名前のパラメーターを受け取ることができる仕組みです。

MainLayout.razor
@inherits LayoutComponentBase
@using BlazorTest.Client.Cascade

<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>

    <div class="main">
        <div class="top-row px-4">
            <a href="http://blazor.net" target="_blank" class="ml-md-auto">About</a>
        </div>
        <CascadingValue Value="guestMessage" Name="guest">
            <div class="contexnt px-4">
                @Body
            </div>
        </CascadingValue>
    </div>
</div>

@code{
    private Message guestMessage = new Message();
}

続いて、画面側として CascadingSample.razor を作成しました。

ボタンを押すと、画面にメッセージが表示されるシンプルなものです。

CascadingValue を受け取るには、CascadingParameter 属性を付けた変数を用意します。

渡す側で Name 属性を付けた場合は、受け取る側にもないとエラーになるので、忘れないようにしましょう。

パラメーターがひとつの場合は、CascadingValue と CascadingParameter に Name 属性がなくても正常に動作します。

CascadingSample.razor
@page "/casc"
@using BlazorTest.Client.Cascade

<h3>Cascading Sample</h3>

<button class="btn btn-primary" @onclick="GuestMessage">
    GuestMessage
</button>

<br />

<h4>@messageText</h4>

@code {
    [CascadingParameter(Name = "guest")]
    protected Message guestMessage { get; set; }

    private string messageText;

    private void GuestMessage()
    {
        messageText = guestMessage.GetText();
    }
}

動作確認してみましょう。

ルーティングした URL にアクセスして、GuestMessage のボタンを押してみてください。

下に「Hello Guest!!」のメッセージが表示されたことが確認できました。

cascading-parameter

これでひとつのパラメーターを渡す方法については完了です。

複数のパラメーターを渡す

複数のパラメーターを渡す方法について見ていきましょう。

今度は名前の引数を付けた namedMessage という変数を追加しました。

複数のパラメーターを渡す場合は、CascadingValue のタグをネストしてください。

このとき、受け取る側でどちらもパラメーターなのか判断が必要になるため、Name 属性は必須となります。

MainLayout.razor
@inherits LayoutComponentBase
@using BlazorTest.Client.Cascade

<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>

    <div class="main">
        <div class="top-row px-4">
            <a href="http://blazor.net" target="_blank" class="ml-md-auto">About</a>
        </div>
        <CascadingValue Value="guestMessage" Name="guest">
            <CascadingValue Value="namedMessage" Name="named">
                <div class="contexnt px-4">
                    @Body
                </div>
            </CascadingValue>
        </CascadingValue>
    </div>
</div>

@code{
    private Message guestMessage = new Message();
    private Message namedMessage = new Message("nekojoker");
}

ひとつのパラメーターを渡す画面を修正してもいいですが、CascadingSample2.razor という画面をひとつ追加しました。

ひとつのパラメーターを渡すときも Name 属性を指定したので、特に難しい点はないですね。

CascadingSample2.razor
@page "/casc2"
@using BlazorTest.Client.Cascade

<h3>Cascading Sample2</h3>

<button class="btn btn-primary" @onclick="GuestMessage">
    GuestMessage
</button>

<button class="btn btn-secondary" @onclick="NamedMessage">
    NamedMessage
</button>

<br />

<h4>@messageText</h4>

@code {
    [CascadingParameter(Name = "guest")]
    protected Message guestMessage { get; set; }

    [CascadingParameter(Name = "named")]
    protected Message namedMessage { get; set; }

    private string messageText;

    private void GuestMessage()
    {
        messageText = guestMessage.GetText();
    }

    private void NamedMessage()
    {
        messageText = namedMessage.GetText();
    }
}

動作確認してみましょう。

GuestMessage のボタンを押したときは先ほどと同じ動きとなり、NameMessage を押したときは名前付きでメッセージが表示されることが確認できました。

GuestMessage ボタンを押した場合
cascading-parameter
NamedMessage ボタンを押した場合
cascading-parameter

カスケード値のオーバーライド

ここまで CascadingValue のタグを入れ子にすることも可能という話をしてきましたが、同じ Name 属性のタグを入れ子にすることも可能です。

例えば、Name 属性が named のタグを2つ用意し、overrideMessage として上書きしました。

名前は Bob になっています。

MainLayout.razor
@inherits LayoutComponentBase
@using BlazorTest.Client.Cascade

<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>

    <div class="main">
        <div class="top-row px-4">
            <a href="http://blazor.net" target="_blank" class="ml-md-auto">About</a>
        </div>
        <CascadingValue Value="guestMessage" Name="guest">
            <CascadingValue Value="namedMessage" Name="named">
                <CascadingValue Value="overrideMessage" Name="named">
                    <div class="contexnt px-4">
                        @Body
                    </div>
                </CascadingValue>
            </CascadingValue>
        </CascadingValue>
    </div>
</div>

@code{
    private Message guestMessage = new Message();
    private Message namedMessage = new Message("nekojoker");
    private Message overrideMessage = new Message("Bob");
}

動作確認してみましょう。

NamedMessage のボタンを押すと、nekojoker ではなく Bob の名前が表示されることが確認できました。

cascading-parameter

最後に

CascadingValue と CascadingParameter を使って、パラメーターを渡す方法について解説しました。

最後にもう一度使い方についてまとめておきます。

カスケーディングの使い方

渡す側
  • CascadingValue のタグを使って定義
  • Value 属性に値を定義
  • 複数渡す場合は Name 属性の定義が必須(ひとつの場合は任意)
受け取る側
  • CascadingParameter の属性をプロパティに付与
  • CascadingValue で定義した Name 属性と一致させる

本記事の内容が少しでも参考になれば幸いです。

Blazor の書籍も好評発売中!
blazor-book

入門編から EC サイトを作る応用編まで、Blazor の本を3冊執筆しました。

私が1年以上かけて学習した内容をすべて詰め込んでいるので、さらにステップアップしたい方はぜひご覧ください。