Binding 3

2022. 5. 4. 00:00ASPNET/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}");
    }
}

 

관련영상

https://youtu.be/58Qbbi2iKZ4

 

반응형

'ASPNET > Blazor' 카테고리의 다른 글

이벤트 처리 2  (0) 2022.05.06
이벤트 처리  (0) 2022.05.05
Binding 2  (0) 2022.05.03
Binding 1  (0) 2022.05.02
DynamicComponent  (0) 2022.04.29