Razor記法‐基本
■基本
①HTMLとC#の切り替えは[@]で始まり、半角スペースや改行で終わる。
ex)私は @name です。
この例では変数nameを@nameと指定し、nameプロパティの値を表示している。
(*)@nameの前後には半角スペースが必須!
前に半角スペースがない場合@nameという文字列になり、
後ろに半角スペースがない場合、[@nameです]という名前の変数を使うことになる
・@(name)とすれば、スペースが無くとも正しく処理される。
・またC#で変数名に使えない文字を使っても、スペースが無くとも問題ない。
(*)例えばタグなど。<span>@name</span>だと問題ない。
②@変数名で処理できるのは、プロパティや変数、メソッド等。
Component間のデータ授受(子⇒親)②
■子で起こした引数有のイベントを親で購読する。
●親
@page "/ParentBmi3"
<BlazorBmi.Components.BmiChild3 OnResultChanged="@ChanegResult" />
BMI:@Bmi
@code{
public double Bmi { get; set; }
private void ChanegResult(double result)
{
this.Bmi = result;
}
}
●子
<div>子のイベントを親でハンドル</div>
<div>身長:<input type="number" @bind="Height" /></div>
<div>体重:<input type="number" @bind="Weight" /></div>
<button @onclick="ClickCalc">計算</button>
@code{
public double Weight { get; set; } = 60;
public double Height { get; set; } = 170;
[Parameter]
public EventCallback<double> OnResultChanged { get; set; }
private async void ClickCalc()
{
var result = Weight / *1;
await OnResultChanged .InvokeAsync(result);
}
}
①親では、子呼び出し時に、子のCallbackイベント名と、そのイベントを
検知した時に実行したいメソッドを紐づけておく。
<BlazorBmi.Components.BmiChild3 OnResultChanged="@ChanegResult" />
OnResultChanged:子のCallbackEvent名
@ChanegResult:親に定義している、子のonResultChangedイベント検知時に
行いたい処理(メソッド名)
*1:Height / 100) * (Height / 100
Component間のデータ授受(子⇒親)①
■子での変更を親に伝えたい場合、Event経由で行う必要がある。
■親(呼び出し側)
<PJ名.Components.コンポーネント名 Weight ="@Weight"
Height ="@Height" @bind-Result="Result" />
//親から子への引き渡しはbindは不要
@code{
public double Weight { get; set; } = 60;
public double Height { get; set; } = 170;
public double Result { get; set; } = 0;
}
①@bind-Result="Result"で、子で変更したResultの値が親に渡される。
■子
<div>
Height: @Height cm, Weight:@Weight kg.
</div>
<button class="bnt btn-primary" @onclick="clickCalc">計算</button>
@code{
[Parameter]
public double Height { get; set; } = 170.0;
[Parameter]
public double Weight { get; set; } = 60.0;
[Parameter]
public double Result{get;set; }」
//パラメータの変更を受け取るイベント
[Parameter]
public EventCallback<double> ResultChanged { get; set; }
//計算
public async void clickCalc()
{
Result = Weight/*1;
await ResultChanged.InvokeAsync(Result);
}
①[Parameter]属性付きで、授受したいプロパティを定義
②値変更時に子から親に渡したいプロパティについて、プロパティ名+Changed
という名前で[Parameter]属性付きでEventCallBackを定義しておく。
③子で変更したプロパティを親に伝える場合、変更したプロパティ
Changedイベントを、InvokeAsyncで起こす。
その際、引数に渡す値をセットする。
上の例でいうと、await ResultChanged.InvokeAsync(Result);
(*)例えばWeightなどはChangedイベントを呼んでいないので、
子でWeightの値を変えても親には伝わらない。
■親
①親は、コンポーネント呼び出し時、やり取りするパラメータ名を
@bind-XXX=値という形で子に渡す。
子で、[Parameter]属性付きで定義されたプロパティ名がXXXにセットされる。
(この時、インテリセンスが効く)
*1:Height/100)* (Height / 100
Component間のデータ授受(親⇒子)
■ロード時に1回だけ親から子に渡すケース
●親
<PJ名.Components.コンポーネント名 Param名①="test" Param名②="2021" />
親(コンポーネントを使う側)では、"パラメータ名:値"という形で
コンポーネントに値を渡す。パラメータ名は、子で定義した[Parameter]属性
付きのプロパティ名
●子
<div">Copyright 2020 by @Name @Year</div>
@code {
[Parameter]
public string Name { get; set; }
[Parameter]
public int Year { get; set; }
}
パラメータは、[Parameter]属性を付けたプロパティで定義する。
bindする場合としない場合
■bindする場合としない場合
①<input type="text" @bind=変数 />
②<input type="text" @value=変数 />
①も②もどちらも変数の値がセットされるが、
・bindした場合は、テキストの値を画面で変更時、変更値がCode側の変数に格納され、
変数の値をCode側で変更時、画面に反映される。(双方向)
・bindしない場合は、Code側での値変更が画面に反映はされるが、
画面で変更した値は変数には格納されない。(単方向)
双方向データバインディング
■値を別の要素に表示する
@*テキストボックスで入力*@
<input class="form-control" @bind="Title"/>
@*入力値が保存されるプロパティ*@
private string Title { get; set; }
@*入力値をラベルに表示*@
<label class="col-form-label">@Title</label>
■即時反映する
上記例の場合、ロストフォーカス時にラベルに反映される。
入力値を即時反映する場合は、"oninput"inputにイベントを追加する。
<input class="form-control" @bind:event ="oninput" @bind="Title2" />
(*)この時、bindをbind-valueにすると、inputのvalue要素へのbindとなる
value要素へのbindの場合、単方向のバインドとなり、画面での入力が
プロパティに反映されない為、oninputイベントは走らない。
■入力値を加工して反映する
入力値はプロパティのSetterを通して保存され、Getterを通して反映される為、
そこに処理を追加してやれば良い。
(*)入力値に"test"を足して反映
private string _Title2;
public string Title2
{
get { return _Title2; }
set { _Title2 = value + "test"; }
}
■Styleにバインドする
<input type ="number" @bind ="fontSizeNum" class="form-control" />
<div style="font-size:@(fontSizeNum)pt">確認するよ</div>
@code
{
private int fontSizeNum{ get; set; } = 12;
}
■CSSにバインドする
<input type ="number" @bind ="fontSizeNum" class="form-control" />
<div class="fontSize">確認するよ</div>
<style>
div.fontSize{color:green;font-size:@(fontSizeNum)pt;}
</style>
@code
{
private int fontSizeNum{ get; set; } = 12;
}
実際はClass属性をバインド先にし、Classを切り替える使い方が良いが。
Child Components
■Components
・Blazorで作る一つ一つの要素(Pageなど)をComponentsという。
機能ごとに個別にComponentsを作り、それを適宜ページで呼び出す
ことでシステムを構築していくことができる
■Child Cpomponents
・Pageの任意の場所から呼び出すComponentをChild Componentという。
①配置場所
・通常、Componentsフォルダを作りその中に配置する。
②作成方法
・Pageと同じだが、ルーティングに関する記載は不要
ex)ChildRazor.razor
<div>@Item.Name</div>
<div>@Item.Height</div>
@code {
@*パラメータ付きで呼ばれる場合はParameter属性付与*@
[Parameter]
public BmiItem Item { get; set; }
[Parameter]
public RenderFragment ChildContnet { get; set; }
}
@*以下のClassは別ファイルで定義*@
@code {
public class BmiItem
{
public string Name { get; set; }
public double Height { get; set; }
}
}
③呼び方
呼び出したいrazor内で、以下のように呼ぶ。
<BlazorBmi.Components.ChildRazor Item="@it" />