-
Parameter, Ref, EventCallback웹 서버/Blazor 입문 2022. 4. 27. 22:34
1. 컴포넌트화
아래의 코드를 분석할 필요는 없다.
User.razor
@page "/user" @using BlazorApp.Data <h3>Online User</h3> <p> Users: <b>@_users.Count()</b> </p> <br /> <ul class="list-group"> @foreach (UserData user in _users) { <li @key="user" class="list-group-item"> <button type="button" class="btn btn-link" @onclick="(()=>KickUser(user))">ban</button> <label>@user.Name</label> </li> } </ul> <br /> <div class="container"> <div class="row"> <div class="col"> <input class="form-control" placeholder="Add User" @bind-value="_inputName" /> </div> <div class="col"> <button class="@_btnClass" type="button" @onclick="AddUser" disabled="@(_users.Count() >= 5)">Add a User</button> </div> </div> </div> @code { List<UserData> _users = new List<UserData>(); string _inputName; string _btnClass = "btn btn-primary"; protected override void OnInitialized() // User에 접근해서 페이지를 열면 초기화되는 함수 { _users.Add(new UserData() { Name = "Rookiss" }); _users.Add(new UserData() { Name = "Faker" }); _users.Add(new UserData() { Name = "Deft" }); RefreshButton(); } void AddUser() { _users.Add(new UserData() { Name = _inputName }); _inputName = ""; RefreshButton(); } void KickUser(UserData user) { _users.Remove(user); RefreshButton(); } void RefreshButton() // 유저수가 홀수짝수에 따라 버튼색이 바뀜 { if (_users.Count % 2 == 0) _btnClass = "btn btn-primary"; else _btnClass = "btn btn-secondary"; } }
우선 위의 코드 중에서 다음의 코드를 가져와 컴포넌트로 만들 수 있다.
ShowUser.razor
<p> Users: <b>@_users.Count()</b> </p> <br /> <ul class="list-group"> @foreach (UserData user in _users) { <li @key="user" class="list-group-item"> <button type="button" class="btn btn-link" @onclick="(()=>KickUser(user))">ban</button> <label>@user.Name</label> </li> } </ul>
User.razor에 있는 코드를 일부 잘라와서 ShowUser.razor파일에 넣었다.
참고로 컴포넌트 목적의 razor파일은 @page와 같은 경로 설정의 필요성이 사라진다.
User.razor
@page "/user" @using BlazorApp.Data <h3>Online User</h3> <ShowUser></ShowUser> <br />
그리고 원래의 코드가 있던자리에는 위와같이 <ShowUser></ShowUser>를 채워넣어주면된다. ShowUser는 User파일에서 컴포넌트로써 작동하고 있다.
2. Parameter
컴포넌트화 했을 때는 한 가지 문제점이 있다. User.razor에서 정의된 데이터를 ShowUser.razor가 사용할 수 없다는 문제이다. 그래서 이러한 것을 해결하기 위해 Parameter라는 기능을 활용할 수 있다.
ShowUser.razor
@code { [Parameter] public List<UserData> Users { get; set; } // 파라미터를 사용하기 위해선 프로퍼티를 써야함. }
[Parameter]는 파라미터를 사용하겠다는 뜻이다.
그리고 넘겨받을 List타입을 정의하고, public과 프로퍼티를 사용해야한다.
User.razor
<ShowUser Users="_users"></ShowUser> @code { List<UserData> _users = new List<UserData>(); }
그리고 User.razor에서는 위와같은 방법으로 ShowUser.razor에 리스트 정보를 넘겨줄 수 있다.
3. Ref
파라미터로 자료를 넘겨줄 수 있다는 것 까진 알았다. 그런데 한 가지 문제점이 더 있다.
User.razor에 정의된 함수를 ShowUser.razor에서 어떻게 처리하냐는 문제이다.
이러한 문제는 ref키워드를 통해서 User.razor에서 ShowUser.razor에 있는 함수에 접근하는 방식으로 처리한다.
ShowRazor.razor
@code { [Parameter] public List<UserData> Users { get; set; } // 파라미터를 사용하기 위해선 프로퍼티를 써야함. public void AddUser(UserData user) { Users.Add(user); } }
우선은 ShowUser.razor에 @code부분에서 public형으로 함수를 정의해준다.
User.razor
<ShowUser Users="_users" @ref="_showUser"></ShowUser> @code { List<UserData> _users = new List<UserData>(); ShowUser _showUser; // ShowUser형 정의 string _inputName; void AddUser() { _showUser.AddUser(new UserData() { Name = _inputName }); // ShowUser의 함수 사용 _inputName = ""; }
그리고 ShowUser타입의 변수를 정의하고 정의된 변수 ref키워드로 정의된 변수(_showUser)와 바인딩을 하면 ShowUser에 대한 함수 접근이 가능해진다.
4. EventCallback
ref를 통해서 부모 컴포넌트에서 자식 컴포넌트의 함수와 변수를 사용할 수 있었다. 반대로 자식 컴포넌트(ShowUser.razor)에서 부모 컴포넌트(User.razor)의 함수를 호출하고 싶을 때는 어떻게 해야할까?
ShowUser.razor
@code { [Parameter] public List<UserData> Users { get; set; } // 파라미터를 사용하기 위해선 프로퍼티를 써야함. [Parameter] public EventCallback CallbackTest { get; set; } //Action과 Fucn도 사용이 가능하지만 EventCallback을 추천 protected override void OnInitialized() // User에 접근해서 페이지를 열면 초기화되는 함수 { Users.Add(new UserData() { Name = "Rookiss" }); Users.Add(new UserData() { Name = "Faker" }); Users.Add(new UserData() { Name = "Deft" }); } public void AddUser(UserData user) { Users.Add(user); } public void KickUser(UserData user) { Users.Remove(user); CallbackTest.InvokeAsync(null); // EventCallback 사용방식 } }
파라미터로 이벤트함수 관련인 EventCallback으로 변수를 선언한다.
그리고 KickUser가 호출되면 EventCallback이 간접 호출이 되게 KickUser()함수안에 구현하였다.
User.razor
<ShowUser Users="_users" CallbackTest="CallbackTestFunc" @ref="_showUser"></ShowUser> @code { List<UserData> _users = new List<UserData>(); ShowUser _showUser; string _inputName; void AddUser() { _showUser.AddUser(new UserData() { Name = _inputName }); _inputName = ""; } void KickUser(UserData user) { _showUser.KickUser(user); } void CallbackTestFunc() { _inputName = "CallbackTest"; StateHasChanged(); } }
CallbackTest파라미터를 CallbackTestFunc와 바인딩을해주면 ShowUser.razor에 있는 KickUser가 호출될 때 마다
User.razor에 있는 CallbackTestFucn()가 간접적으로 호출이된다.
'웹 서버 > Blazor 입문' 카테고리의 다른 글
Templated Component (0) 2022.05.20 Cascading Parameter (0) 2022.05.19 Binding (0) 2022.04.25