BlazorでSPAするぞ!(3) - パラメータ - 正式版対応済
※最終更新日: 2020/5/24 正式リリース版に対応修正しました。
という事で、↓↓↓の続きです。
前回 Component の基本的な作り方・使い方を見てみましたが、今回はComponentのパラメータ機能を見ていきます。
1. パラメータ(Parameter)の利用
コンポーネントは、コンポーネント(ページ等)内にネストして配置することができました。
そして以下のように タグ で配置しました。
以下は、PersonViewerコンポーネントを .razor に配置しています(PersonViewerはPerson情報を表示するコンポーネントを想定)。
<PersonViewer />
コンポーネントではタグ属性を利用して、親(コンテナとなっているコンポーネント)から子(配置されているコンポーネント)へパラメータを渡すことができます。
以下ではPersonViewerコンポーネントに対して「ID / FirstName / LastName」の3つのパラメータを渡しています。
<PersonViewer1 ID="@CurrentPerson.ID" FirstName="@CurrentPerson.FirstName" LastName="@CurrentPerson.LastName" />
1.1. サンプル実装
では具体的なサンプル実装を。
プロジェクトを作成します。
dotnet new blazorwasm -o component_param_blazor
(1) モデルクラスを作成
Personモデルクラスを作成します(Models/Person.cs)。
# Models/Person.cs # using System; namespace component_param_blazor.Models { public class Person { public int ID { get; set; } public string FirstName{ get; set; } public string LastName{ get; set; } } }
(2) コンポーネントを作成
PersonViewerコンポーネントを作成します(Components/PersonViewer1.razor)。
# Components/PersonViewer1.razor # @using component_param_blazor.Models <div class="container"> <div class="row"> <div class="col-sm">ID:</div> <div class="col-sm">@ID</div> </div> <div class="row"> <div class="col-sm">FirstName:</div> <div class="col-sm">@FirstName</div> </div> <div class="row"> <div class="col-sm">LastName:</div> <div class="col-sm">@LastName</div> </div> </div> @code { [Parameter] public int ID { get; set; } [Parameter] public string FirstName{ get; set; } [Parameter] public string LastName{ get; set; } }
[Parameter]
親コンポーネントがらパラメータとして受け取るプロパティには [Parameter] 属性を付けます。
親コンポーネントからの受取ですが、アクセス修飾子はprivateでもOKです。 (← Preview版の時はprivateで行けてた気がする)
(3) PersonViewerコンポーネントをページに配置
Pages/Index.razorにPersonViewer1コンポーネントを配置します。
Index.razorのコードブロックで Personオブジェクト を作成して、PersonViewer1コンポーネントにパラメータとして各価を引き渡します。
# Pages/Index.razor # @page "/" @using component_param_blazor.Components @using component_param_blazor.Models <PersonViewer1 ID="@CurrentPerson.ID" FirstName="@CurrentPerson.FirstName" LastName="@CurrentPerson.LastName" /> @code { private Person CurrentPerson { get; set; } protected override void OnInitialized() { this.CurrentPerson = new Person() { ID = 0, FirstName = "takashi", LastName = "sakata" } ; } }
実行画面は以下の通りです。
1.2. サンプル実装(オブジェクトとしてパラメータを渡す)
[Parameter]属性で引き渡すパラメータは、リテラル型だけでなく任意のオブジェクト型も指定可能です。
先程の PersonViewer1.razor を Personオブジェクト を受け取るように修正した版(PersonViewer2.razor)が以下です。
# Components/PersonViewer2.razor # @using component_param_blazor.Models <div class="container"> <div class="row"> <div class="col-sm">ID:</div> <div class="col-sm">@Person.ID</div> </div> <div class="row"> <div class="col-sm">FirstName:</div> <div class="col-sm">@Person.FirstName</div> </div> <div class="row"> <div class="col-sm">LastName:</div> <div class="col-sm">@Person.LastName</div> </div> </div> @code { [Parameter] public Person Person { get; set; } }
# Pages/Index.razor # @page "/" @using component_param_blazor.Components @using component_param_blazor.Models <PersonViewer2 Person="@CurrentPerson" /> @code { private Person CurrentPerson { get; set; } protected override void OnInitialized() { this.CurrentPerson = new Person() { ID = 0, FirstName = "takashi", LastName = "sakata" } ; } }
2. Cascading Parameter
親子間のプロパティの受け渡しは、前述の通りコンポーネント定義にプロパティ設定を行えば可能です。
親子関係の階層が深くなった場合に、数珠繋ぎが煩雑になることに対する解決策の1つが Cascading Parameter です。
2.1. 単純なパラメータの引き回し
まず、親から子にパラメータを引き渡す前述の方法を使った場合の、パラメータの引き回し例です。
子の配下に孫コンポーネントがあり、パラメータオブジェクトをそのまま引き継ぐ必要がある場合、↓↓↓のように実装すれば可能です。
# Pages/Index.razor # @page "/" @using cascading_parameter_blazor.Components <ChildComponent YourName="@YourName" /> @code { private string YourName = "ryuichi111std"; }
# Components/ChildComponent.razor (子コンポーネント)# this is Child. <br /> @YourName <br /> <GrandChildComponent YourName="@YourName" /> @code { [Parameter] public string YourName { get; set; } }
# Components/GrandChildComponent.razor (個コンポーネントに配置される 孫コンポーネント)# this is GrandChild. <br /> @YourName @code { [Parameter] public string YourName { get; set; } }
2.2. Cascadingパラメータによる引き回し
が、面倒なので、Cascading Parameter機能を使えば、子孫までパラメータを一括で引き回せます。
以下が実装サンプル。
(1) 親コンポーネントの実装
# Pages/Index.razor # @page "/" @using component_param_blazor.Components <div class="container bg-primary"> <CascadingValue Value="YourName" Name="YourNameParam"> <ChildComponent /> </CascadingValue> </div> @code { private string YourName = "ryuichi111std"; }
【CascadingValue】
パラメータを提供するコンポーネントで「<CascadingValue>要素」を定義し、その子要素としてパラメータを引き継ぎたいコンポーネントを配置します。
Value属性値はパラメータの値。@code {} コードブロックで定義した YourName 値を渡しています。
Name属性値はパラメータ名。子孫コンポーネントは Value属性で指定した@YourNameの値を YourNameParam というパラメータとして参照することができます。
(2) 子コンポーネントの実装
# Components/ChildComponent.razor # <div class="container bg-secondary"> this is Child. <br /> @YourName <br /> <GrandChildComponent /> </div> @code { [CascadingParameter (Name = "YourNameParam")] private string YourName { get; set; } }
【CascadingParameter属性】
プロパティ定義に対して「CascadingParameter属性」を付与します。
親要素で定義されたCascadingValueの中からYourNameParamという名前のパラメータを、自コンポーネントのYourNameプロパティの値として取得する、という意味になります。
(3) 孫コンポーネントの実装
# Components/GrandChildComponent.razor # <div class="container bg-success"> this is GrandChild. <br /> @YourName </div> @code { [CascadingParameter (Name = "YourNameParam")] private string YourName { get; set; } }
こちらも同様に「CascadingParameter」属性をプロパティに付与することでパラメータを引き継ぐことができます。
実行画面は以下の通りです。
3. まとめ
ということでComponentのパラメータでした。
(ぜんぜん、まとめじゃない・・・)