DynamicComponent

2022. 4. 29. 00:00ASPNET/Blazor

반응형

.NET6의 Blazor에서는 Razor Component 의 동적 렌더링을 위한 'DynamicComponent'를 도입했다. 

따라서 DynamicComponent를 사용하면 조건부 논리를 사용하지 않고도

다양한 유형의 Component 를 매우 쉽게 렌더링할 수 있다. 

또한 동적으로 렌더링할 때 해당 Component 에 적절한 매개변수를 전달할 수 있다.

 

위 DynamicComponent 를 Test 하기 전에

기본적인 Blazor Server Project 를 생성 하자

https://yogingang.tistory.com/131

 

Blazor Server Create Project

1. VisualStudio 2022 새 프로젝트 만들기 선택 2. Blzor Server App 선택 Next 3. Project name 및 Loacation 설정 Next 4. Framework 및 추가 정보 입력 Create 5. Project 구성 wwwroot 앱의 퍼블릭 정적..

yogingang.tistory.com

 

Pages/DynamicTest.razor 생성

 

@page "/dynamic-component"
 
<PageTitle>dynamic-component</PageTitle>
 
<div class="container">
    <div class="row">
        <div class="col col-md-4 offset-md-3">
            <select class="form-select" aria-label="Default select example" @onchange="OnComponentSelect">
                <option value="">-Select-</option>
                <option value="@(nameof(Counter))">Counter Component</option>
                <option value="@(nameof(FetchData))">Fetch Data Component</option>
            </select>
        </div>
    </div>
    <div class="col mt-4">
        @if (selectedComponent != null)
        {
            <DynamicComponent Type="@selectedComponent"></DynamicComponent>
        }
    </div>
</div>
<h1><span class="text-danger">it is dynamic component test</span></h1>

@code {
    private Type? selectedComponent;
    private void OnComponentSelect(ChangeEventArgs e)
    {
        selectedComponent = e?.Value?.ToString()?.Length > 0 ?
        Type.GetType($"BlazorTutorial.Pages.{e.Value}") : null;
    }
}

 

해당 영역에서 BlazorTutorial --> 생성한 Project NameSpace 

Counter.razor 와 FetchData.razor 가  위치하는 곳이다.  

{APP NAMESPACE}.Pages.{e.Value}

 

매개변수 전달

아래는 위 counter 와 fetchdata 에 대한 title 을 parameter 로 전달하는 예제 입니다.

 

Data/DynamicComponentParameters

namespace BlazorTutorial.Data;
public class DynamicComponentParameters
{
    public Dictionary<string, object> Parameters { get; set; } = new Dictionary<string, object>();
}

 

Pages/MyCounter

@page "/my-counter"

<PageTitle>Counter</PageTitle>

<h1>@Title</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }

    [Parameter]
    public string Title{get;set;} = "Counter";
}

기존  Counter.razor 에서 [Parameter] Title 이 추가 되었다.

그리고 해당 @Title  을 표시하도록 수정 하였다.

 

Pages/MyFetchData

@page "/my-fetchdata"

<PageTitle>Weather forecast</PageTitle>

@using BlazorTutorial.Data
@inject WeatherForecastService ForecastService

<h1>@Title</h1>

<p>This component demonstrates fetching data from a service.</p>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    private WeatherForecast[]? forecasts;

    protected override async Task OnInitializedAsync()
    {
        forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
    }

    [Parameter]
    public string Title { get; set; } = "Weather forecast";
}

기존  FetchData.razor 에서 [Parameter] Title 이 추가 되었다.

그리고 해당 @Title  을 표시하도록 수정 하였다.

 

Pages/DynamicTestWithParameter.razor

@page "/dynamic-component/parameters"
@using BlazorTutorial.Data
 
<PageTitle>dynamic-component</PageTitle>
 
<div class="container">
    <div class="row">
        <div class="col col-md-4 offset-md-3">
            <select class="form-select" aria-label="Default select example" @onchange="OnComponentSelect">
                <option value="">-Select-</option>
                <option value="@(nameof(MyCounter))">Counter Component</option>
                <option value="@(nameof(MyFetchData))">Fetch Data Component</option>
            </select>
        </div>
    </div>
    <div class="col mt-4">
        @if (selectedComponent != null)
        {
            <DynamicComponent 
            Type="@selectedComponent"
            Parameters="@dynamicComponentParameters[selectedComponent.Name].Parameters"
            ></DynamicComponent>
        }
    </div>
</div>
<h1><span class="text-danger">it is dynamic component test</span></h1>

@code {
    private Type? selectedComponent;
    private void OnComponentSelect(ChangeEventArgs e)
    {
        selectedComponent = e?.Value?.ToString()?.Length > 0 ?
        Type.GetType($"BlazorTutorial.Pages.{e.Value}") : null;
    }

    private Dictionary<string, DynamicComponentParameters> dynamicComponentParameters = new()
    {
        {
            "MyCounter",
            new DynamicComponentParameters()
            {
                Parameters = new() {{"Title", "My Counter"}}
            }
        },
        {
            "MyFetchData",
            new DynamicComponentParameters()
            {
                Parameters = new() {{"Title", "My Fetch Data"}}
            }
        }
    };
}

dynamicComponentParameters 를 통해 각 parameter 와 component 를 mapping 해준다. 

Parameters 에 dynamicComponentParameters 에 접근하여 Parameters 를 설정하도록 한다.

 

Title 이 Counter 에서 parameter 로 전달한 My Counter 로 바뀌었다.

 

Title 이 Fetch Data 에서 parameter 로 전달한 My Fetch Data 로 바뀌었다.

 

 

관련영상

https://youtu.be/BdYDrkPzeKA

반응형

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

Binding 2  (0) 2022.05.03
Binding 1  (0) 2022.05.02
JavaScript Interop - CallingCSharpMethod  (0) 2022.04.28
JavaScript Interop - CallingJavaScript 2/2  (0) 2022.04.27
JavaScript Interop - CallingJavaScript 1/2  (0) 2022.04.26