Binding 3
2022. 5. 4. 00:00ㆍASPNET/Blazor
반응형
여러 중첩된 구성 요소에 바인딩
Pages/Parent.razor
@page "/multi-binding/parent"
<h1>Parent Component</h1>
<p>Parent Message: <b>@parentMessage</b></p>
<p>
<button @onclick="ChangeValue">Change from Parent</button>
</p>
<Child @bind-ChildMessage="parentMessage" />
@code {
private string parentMessage = "Initial value set in Parent";
private void ChangeValue()
{
parentMessage = $"Set in Parent {DateTime.Now}";
}
}
Pages/Child.razor
<div class="border rounded m-1 p-1">
<h2>Child Component</h2>
<p>Child Message: <b>@ChildMessage</b></p>
<p>
<button @onclick="ChangeValue">Change from Child</button>
</p>
<GrandChild @bind-GrandchildMessage="BoundValue" />
</div>
@code {
[Parameter]
public string? ChildMessage { get; set; }
[Parameter]
public EventCallback<string> ChildMessageChanged { get; set; }
private string BoundValue
{
get => ChildMessage ?? string.Empty;
set => ChildMessageChanged.InvokeAsync(value);
}
private async Task ChangeValue()
{
await ChildMessageChanged.InvokeAsync(
$"Set in Child {DateTime.Now}");
}
}
Pages/GrandChild.razor
<div class="border rounded m-1 p-1">
<h3>Grandchild Component</h3>
<p>Grandchild Message: <b>@GrandchildMessage</b></p>
<p>
<button @onclick="ChangeValue">Change from Grandchild</button>
</p>
</div>
@code {
[Parameter]
public string? GrandchildMessage { get; set; }
[Parameter]
public EventCallback<string> GrandchildMessageChanged { get; set; }
private async Task ChangeValue()
{
await GrandchildMessageChanged.InvokeAsync(
$"Set in Grandchild {DateTime.Now}");
}
}
유의 할 점
일반적으로 자체 구성 요소 매개 변수에 직접 쓰는 구성 요소는 사용 금지
Child 구성 요소는 ChildMessage 매개 변수에 직접 쓰는 대신 BoundValue 속성을 사용함
아래와 같이 Child.razor 를 변경할 경우 GrandChild 로 부터의 변경 사항을 parent 까지 전달 할 수 없다.
그 문제를 해결 하기 위해 ChildMessage 의 set 영역에서 ChildMessageChanged.InvokeAsync 를 할 경우 무한 loop 를 하게 된다.
Pages/Child.razor (Parent.razor 에 data 전달 불가)
GrandChild.razor 의 변경을 child 는 인식 하지만 parent 쪽으로 넘겨줄 방법이 없다.
<div class="border rounded m-1 p-1">
<h2>Child Component</h2>
<p>Child Message: <b>@ChildMessage</b></p>
<p>
<button @onclick="ChangeValue">Change from Child</button>
</p>
<GrandChildDirect @bind-GrandchildMessage="ChildMessage" />
</div>
@code {
[Parameter]
public string? ChildMessage { get; set; }
[Parameter]
public EventCallback<string> ChildMessageChanged { get; set; }
//private string BoundValue
//{
// get => ChildMessage ?? string.Empty;
// set => ChildMessageChanged.InvokeAsync(value);
//}
private async Task ChangeValue()
{
await ChildMessageChanged.InvokeAsync(
$"Set in Child {DateTime.Now}");
}
}
Pages/Child.razor (무한 루프)
<div class="border rounded m-1 p-1">
<h2>Child Component</h2>
<p>Child Message: <b>@ChildMessage</b></p>
<p>
<button @onclick="ChangeValue">Change from Child</button>
</p>
<GrandChildDirect @bind-GrandchildMessage="ChildMessage" />
</div>
@code {
private string? boundValue;
[Parameter]
public string? ChildMessage { get =>boundValue;
set
{
boundValue = value;
ChildMessageChanged.InvokeAsync(value);
}
}
[Parameter]
public EventCallback<string> ChildMessageChanged { get; set; }
//private string BoundValue
//{
// get => ChildMessage ?? string.Empty;
// set => ChildMessageChanged.InvokeAsync(value);
//}
private async Task ChangeValue()
{
await ChildMessageChanged.InvokeAsync(
$"Set in Child {DateTime.Now}");
}
}
관련영상
반응형