Blazor 필수 사항: 단계별 가이드
Blazor 시작하기
Blazor는 현대 웹앱 개발을 위한 가장 인기 있고 널리 사용되는 프레임워크 중 하나가 되고 있습니다. 본질적으로 C#, Razor 구문 및 HTML을 사용하여 클라이언트 측 SPA(단일 페이지 애플리케이션)를 구축할 수 있는 .NET 웹 프레임워크를 나타냅니다. 구성 요소 기반 아키텍처, 페이지 간 공유 가능한 UI 요소, JavaScript 상호 운용성 등과 같은 수많은 이점을 제공하므로 다음 프로젝트에서 이를 사용하기 시작할 이유가 많습니다.
Blazor 및 Ignite UI for Blazor 작동 방식을 더 잘 이해하기 위해 예제, 코드 조각 및 사용 사례가 포함된 Quick Blazor 필수 가이드를 만들었습니다.
Blazor 필수품
Blazor 란 무엇입니까?
Blazor는 C#, Razor 구문 및 HTML을 사용하여 클라이언트 측 애플리케이션을 만들 수 있는 .NET 웹 프레임워크입니다. 이를 통해 C#을 사용하여 풍부하고 현대적인 SPA(단일 페이지 애플리케이션)를 만들고 선택한 브라우저에서 실행할 수 있습니다.
"Blazor "라는 이름은 브라우저에서 C# 및 Razor 실행하는 프레임워크의 기능에서 유래되었습니다. "browser"와 "Razor "를 결합하면 "Blazor "라는 이름이 붙습니다.
왜 Blazor 사용해야 할까요?
- Blazor 사용하면 현대적이고 기능이 풍부한 언어인 C#을 사용하여 풍부하고 대화형 UI를 만들 수 있습니다.
- 클라이언트와 서버 모두와 공유하여 앱 로직을 재사용할 수 있습니다. 이를 통해 우리는 전체 스택 .NET 개발 경험을 가질 수 있습니다.
- 기존 .NET API와 도구를 사용하여 풍부한 웹 애플리케이션을 만들 수 있습니다.
- Blazor Visual Studio와 Visual Studio Code 모두에서 지원됩니다. 이는 Linux, Windows 및 Mac을 포함한 여러 플랫폼에서 뛰어난 .NET 개발 환경을 제공합니다.
- 모바일 브라우저를 포함한 모든 최신 브라우저에서 지원됩니다.
- 훌륭한 커뮤니티 지원을 제공하는 오픈 소스 프레임워크입니다.
- IIS, Azure 앱 서비스 및 Docker를 사용하여 앱을 쉽게 호스팅할 수 있습니다.
Blazor의 특징
- 구성 요소 기반 아키텍처: Blazor는 풍부하고 구성 가능한 UI를 만들 수 있는 구성 요소 기반 아키텍처를 제공합니다.
- 레이아웃: 레이아웃 기능을 사용하여 페이지 전체에서 공통 UI 요소(예: 메뉴)를 공유할 수 있습니다.
- JavaScript 상호 운용성: 이를 통해 JavaScript에서 C# 메서드를 호출할 수 있고 C# 코드에서 JavaScript 함수 또는 API를 호출할 수 있습니다.
- 라우팅: 라우팅을 통해 클라이언트 요청을 한 구성 요소에서 다른 구성 요소로 리디렉션할 수 있습니다.
- 양식 및 유효성 검사: 대화형 양식을 만들어 사용자 입력을 처리하고 유효성 검사 기술을 적용하여 양식의 오류를 처리할 수 있습니다.
- 상태 관리: 브라우저 메모리에 사용자의 앱 상태를 유지할 수 있습니다. 그러나 사용자가 브라우저를 다시 열거나 페이지를 다시 로드하면 브라우저 메모리에 보관된 사용자 상태가 손실됩니다.
- 세계화 및 지역화: Blazor 앱은 다양한 문화와 언어를 사용하는 사용자가 액세스할 수 있도록 만들 수 있습니다. 이를 통해 우리는 애플리케이션의 범위를 전 세계 사용자로 확장할 수 있습니다.
- 프로그레시브 웹 애플리케이션: Blazor 앱을 프로그레시브 웹 애플리케이션으로 만들 수 있습니다. 이렇게 하면 Blazor 앱이 사용자의 네트워크 속도에 관계없이 오프라인으로 작동하고 즉시 로드될 수 있습니다.
- 지연 로딩: 지연 로딩을 사용하면 필요할 때까지 일부 애플리케이션 어셈블리의 로딩을 지연할 수 있습니다. 이렇게 하면 애플리케이션의 시작 성능이 향상됩니다.
- 디버깅: Microsoft Edge 및 Google Chrome과 같은 Chromium 기반 브라우저에서 Blazor WebAssembly 앱을 디버깅할 수 있습니다. 또한 Firefox에서도 디버깅 지원이 가능해졌습니다(현재는 미리보기 단계입니다). Visual Studio 및 Visual Studio Code IDE에서 앱을 디버그할 수도 있습니다.
Blazor 호스팅 모델
Blazor의 구성 요소 모델은 UI 변경 사항 계산을 담당합니다. 그러나 다양한 렌더러를 사용하여 UI 표시 및 업데이트 방법을 제어할 수 있습니다. 이러한 렌더러를 호스팅 모델이라고 합니다.
Blazor 두 가지 호스팅 모델을 지원합니다.
- Blazor 웹어셈블리
- Blazor 서버
Blazor 서버 실행 모델
Blazor 서버란 무엇입니까?
Blazor 서버 호스팅 모델을 사용하면 Blazor 애플리케이션이 전체 .NET 런타임을 기반으로 서버에서 실행될 수 있습니다.
Blazor 서버는 어떻게 작동하나요?
Blazor 서버 실행 모델은 아래 이미지에 표시되어 있습니다.
사용자가 애플리케이션을 로드하면 서버와의 실시간 양방향 SignalR 연결을 설정하는 작은 JavaScript 파일(blazor.server.js)이 브라우저에 다운로드됩니다.
그러면 앱과의 모든 사용자 상호 작용은 기본적으로 WebSocket 프로토콜을 사용하여 SignalR 연결을 통해 서버로 다시 전송됩니다. 서버는 클라이언트의 요청을 처리합니다. 서버가 완료되면 모든 UI 업데이트가 클라이언트로 다시 전송되어 DOM에 적용됩니다.
서버는 연결된 각 클라이언트의 상태를 유지합니다. 이 상태를 회로라고 합니다.
브라우저에서 앱을 실행하면 회로가 생성됩니다. 브라우저에 있는 앱의 각 인스턴스는 서버에 새로운 회로를 만듭니다. 즉, 동일한 브라우저의 서로 다른 두 탭에서 앱을 열면 서버에 두 개의 회로가 생성됩니다.
브라우저를 닫거나 외부 URL로 이동하여 앱이 닫히면 회로 및 관련 리소스가 즉시 해제됩니다.
Blazor 서버 사용의 장점
Blazor 서버는 다음과 같은 이점을 제공합니다.
- 앱의 다운로드 크기는 Blazor WebAssembly 앱에 비해 훨씬 작습니다. 이렇게 하면 앱을 더 빠르게 로드하는 데 도움이 됩니다.
- Blazor 서버 앱은 .NET 호환 API와 같은 서버 기능을 최대한 활용합니다.
- 앱이 서버에서 실행되므로 디버깅과 같은 기존 .NET 도구를 최대한 활용할 수 있습니다.
- 앱의 코드 베이스는 클라이언트와 공유되지 않습니다.
Blazor 서버는 언제 사용하나요?
Blazor 서버 앱은 다음 시나리오에서 선호됩니다.
- 앱을 빠르게 로드하고 싶을 때.
- 앱이 서버 및 네트워크 리소스에 액세스하기를 원하는 경우.
- 모든 사용자 상호 작용에는 네트워크 홉이 포함되므로 Blazor 서버 앱에서 대기 시간이 길어집니다. 따라서 높은 대기 시간이 문제가 되지 않는 Blazor 서버를 선택하세요.
- 모든 무거운 작업은 서버에서 수행되므로 클라이언트 리소스가 제한되어 있는 경우 Blazor 서버가 선호됩니다.
- Blazor 서버는 WebAssembly를 지원하지 않는 브라우저에 적합합니다.
Blazor 웹어셈블리
Blazor WebAssembly란 무엇인가요?
Blazor WebAssembly(WASM) 호스팅 모델을 사용하면 Blazor 앱이 WebAssembly 기반 .NET 런타임의 브라우저에서 클라이언트 측에서 실행될 수 있습니다. Blazor의 주요 호스팅 모델입니다.
Blazor WebAssembly는 어떻게 작동하나요?
Blazor WASM 실행 모델은 아래 이미지에 표시되어 있습니다.
사용자가 애플리케이션을 로드하면 작은 JavaScript 파일(blazor.webassemble.js)이 브라우저에 다운로드됩니다.
이 파일은 다음 두 가지 작업을 처리합니다.
- Blazor 앱 및 브라우저에 대한 종속성과 함께 .NET 런타임을 다운로드합니다.
- 앱을 실행하기 위해 .NET 런타임을 초기화합니다.
앱 실행은 브라우저 UI 스레드에서 직접 발생합니다. UI 업데이트 및 이벤트 처리도 동일한 프로세스 내에서 발생합니다.
클라이언트에 정적 콘텐츠를 제공할 수 있는 웹 서버 또는 기타 서비스를 사용하여 앱 자산을 정적 파일로 배포할 수 있습니다.
Blazor WebAssembly 앱 유형
Blazor WASM 앱에는 두 가지 유형이 있습니다.
- 독립 실행형: 파일을 제공하기 위해 백엔드 ASP.NET Core 앱 없이 배포하기 위해 Blazor WebAssembly 앱을 만든 경우 해당 앱을 독립 실행형 Blazor WASM 앱이라고 합니다.
- 호스팅됨: 파일을 제공하기 위해 백엔드 앱과 함께 배포하기 위해 앱을 만든 경우 해당 앱을 호스팅된 Blazor WASM 앱이라고 합니다. 호스팅된 앱은 .NET을 통해 전체 스택 웹 개발 환경을 제공합니다. 이를 통해 클라이언트와 서버 앱 간에 코드를 공유하고 MVC 및 Razor Pages와의 사전 렌더링 및 통합을 지원할 수 있습니다.
Blazor WebAssembly 사용의 장점
Blazor WebAssembly는 다음과 같은 이점을 제공합니다.
- 앱이 클라이언트에 다운로드되면 서버 측 종속성이 없습니다. 이렇게 하면 서버가 오프라인이 되어도 앱이 계속 작동합니다.
- 클라이언트는 무거운 짐을 지게 될 것입니다. 따라서 서버의 부하가 적습니다.
- 앱은 클라이언트의 리소스를 최대한 활용합니다.
- 앱을 호스팅하는 데 서버가 필요하지 않으므로 서버리스 배포 시나리오가 지원됩니다.
Blazor WebAssembly는 언제 사용하나요?
Blazor WASM 앱은 다음 시나리오에서 선호됩니다.
- 앱이 클라이언트의 리소스를 활용하기를 원할 때.
- 클라이언트가 인터넷에 연결할 수 없는 경우 앱을 오프라인으로 실행해야 하는 경우.
- 앱을 정적 사이트로 호스팅하려는 경우.
Blazor 하이브리드
Blazor 하이브리드란 무엇입니까?
Blazor Hybrid를 사용하면 .NET, HTML 및 CSS를 사용하여 기본 클라이언트 앱을 만들 수 있습니다. .NET MAUI, WPF 및 Windows Forms와 같은 기존 .NET 네이티브 앱 프레임워크를 사용하여 Blazor 하이브리드 앱을 만들 수 있습니다.
Blazor 하이브리드는 어떻게 작동하나요?
Blazor 하이브리드 앱은 기본적으로 장치에서 Razor 구성 요소를 실행합니다. Blazor 구성 요소는 로컬 interop 채널을 통해 포함된 웹 보기 컨트롤로 렌더링됩니다. 구성 요소는 브라우저가 아닌 기본 앱에서 직접 실행됩니다. 따라서 WebAssembly는 하이브리드 앱에 포함되지 않습니다.
하이브리드 앱은 .NET API를 통해 기본 플랫폼의 기능에 액세스할 수 있습니다. 기본 앱인 Blazor 하이브리드 앱은 웹 플랫폼에서만 사용할 수 없는 기능을 지원할 수 있습니다. 또한 Blazor 하이브리드 앱을 사용하여 Blazor 서버 또는 Blazor WASM 애플리케이션의 기존 Razor 구성 요소를 공유하고 재사용할 수도 있습니다.
Blazor Hybrid 사용의 장점
- 이를 통해 Blazor 서버 및 Blazor WASM 애플리케이션의 기존 구성 요소를 재사용할 수 있습니다. 이를 통해 모바일, 데스크톱 및 웹 플랫폼 전반에서 코드 공유 및 재사용이 가능합니다.
- 앱은 장치의 기본 기능을 활용할 수 있습니다.
Blazor Hybrid는 언제 사용하나요?
Blazor Hybrid 앱은 다음 시나리오에서 선호됩니다.
- .NET API를 사용하여 네이티브 앱을 만들고 싶을 때.
- 기본 클라이언트 기능을 활용하려는 경우.
- 앱을 오프라인으로 실행해야 하는 경우.
- 앱의 데이터 처리를 클라이언트에 오프로드하려는 경우
Blazor 구성 요소
Blazor 구성 요소란 무엇입니까?
Blazor 구성 요소는 탐색 모음, 버튼, 양식 등과 같은 UI의 일부로 정의됩니다. Blazor 구성 요소는 확장명이 ".razor"인 Razor 구성 요소 파일로 생성됩니다.
구성 요소는 재사용이 가능하며 여러 프로젝트에서 공유할 수 있습니다. Blazor 구성 요소는 Razor 구성 요소라고도 합니다.
Razor는 HTML과 C# 코드를 결합하기 위한 마크업 구문입니다.
Blazor 구성 요소의 이름은 대문자로 시작해야 합니다.
예 – LoginForm.razor라는 이름은 유효한 구성 요소 이름입니다. loginForm.razor라는 이름은 잘못된 구성 요소 이름입니다.
아래에 표시된 예제 구성요소 코드를 살펴보세요.
@page "/카운터"
<PageTitle>카운터</PageTitle>
<h1>카운터</h1>
<p role="status" >현재 개수: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">나를 클릭하세요</button>
@코드 {
개인 int currentCount = 0;
개인 무효 IncrementCount()
{
현재카운트++;
}
}
@page 지시문은 구성 요소의 경로를 지정하는 데 사용됩니다. @code 지시문은 구성 요소에 대한 C# 코드를 지정하는 데 사용됩니다. IncrementCount 메소드는 버튼 클릭 이벤트에서 호출됩니다.
단일 구성 요소에 대해 여러 개의 고유한 @page 지시문을 사용할 수도 있습니다. 서로 다른 두 구성 요소에 대해 동일한 경로를 설정할 수 없습니다. 그렇게 하면 런타임 오류가 발생합니다.
구성 요소 기본 클래스
HTML과 C# 로직을 분리하기 위해 구성 요소에 대한 기본 클래스를 만들 수 있습니다. 기본 클래스는 ComponentBase 클래스에서 파생되어야 합니다. @inherits 지시문을 사용하여 구성 요소의 기본 클래스를 상속할 수 있습니다.
아래와 같이 기본 클래스 Welcome.razor.cs를 만들었습니다.
Microsoft.AspNetCore.Components 사용;
네임 스페이스 BlazorTutorial.Client.Pages;
public class WelcomeBase : ComponentBase { public string WelcomeMessage { get; set; } = "Blazor 튜토리얼에 오신 것을 환영합니다."; }
아래와 같이 면도기 구성 요소 Welcome.razor를 만들었습니다.
@page "/환영합니다"
@inherits WelcomeBase
<h1>@환영 메시지</h1>
기본 클래스를 상속하기 위해 @inherits 지시문을 사용하고 있습니다.
구성요소 매개변수
구성요소 매개변수는 상위 구성요소에서 하위 구성요소로 데이터를 전달하는 데 사용됩니다.
예를 들어 이를 이해해 보자.
아래와 같이 Child.razor 구성 요소를 만듭니다.
<h3>하위 구성요소</h3>
<p>숫자의 합은 @(num1 + num2)입니다.</p>
@코드 {
[파라미터]
공개 int num1 { 가져오기; 세트; }
[파라미터]
공개 int num2 { 가져오기; 세트; }
}
구성요소 매개변수에는 [Parameter] 속성이 주석으로 추가됩니다. 이 구성요소는 정수 유형의 두 매개변수를 허용하며 두 숫자의 합계를 표시합니다.
아래와 같이 다른 구성 요소 Parent.razor를 만듭니다.
@page "/부모"
<h3>상위 구성요소</h3>
<아동 번호1="5" num2="10"><아동>
Parent 구성 요소 내부에서 Child 구성 요소를 호출하고 두 매개 변수를 모두 전달했습니다.
"@" 기호를 사용하여 매개변수 값에 C# 속성을 할당할 수도 있습니다.
아래에 표시된 예를 살펴보십시오.
@page "/부모"
<h3>상위 구성요소</h3>
<아동 num1="@number1" num2="@number2"><아동>
@코드 {
정수번호1 = 5;
정수2 = 10;
}
[EditorRequired] 속성을 사용하여 매개변수를 필수로 표시할 수 있습니다.
아래에 표시된 예를 살펴보십시오.
<h3>하위 구성요소</h3>
<p>숫자의 합은 다음과 같습니다: @(num1 + num2)<p>
@코드 {
[파라미터]
[편집자필수]
공개 int num1 { 가져오기; 세트; }
[파라미터]
[편집자필수]
공개 int num2 { 가져오기; 세트; }
}
[EditorRequired] 속성을 사용하는 동안 [Parameter] 속성을 사용해야 합니다.
구성요소를 호출하는 동안 필수 매개변수를 제공하지 않으면 컴파일 시간 경고가 발생합니다.
구성요소 매개변수에 기본값을 제공할 수도 있습니다.
아래에 표시된 예를 살펴보십시오.
@page "/환영합니다"
<h1>환영 메시지</h1>
@코드 {
[파라미터]
공개 문자열 WelcomeMessage { get; 세트; } = "환영합니다";
}
Razor 구성 요소 수명 주기
Razor 구성 요소는 생성부터 제거될 때까지 일련의 수명 주기 이벤트를 거칩니다. 동기식 방법과 비동기식 방법이 모두 있습니다. Blazor 프레임워크를 사용하면 수명 주기 메서드를 재정의하여 구성 요소에 대한 추가 작업을 수행할 수 있습니다.
매개변수 설정비동기화
이 메소드는 매개변수가 설정되기 전에 호출됩니다. 상위 구성 요소 또는 구성 요소 경로에서 제공되는 매개 변수를 설정합니다. 구성 요소 매개 변수의 값을 설정하려면 base.SetParametersAsync() 메서드를 호출해야 합니다. 그렇지 않으면 매개변수를 조작하기 위해 사용자 정의 코드를 작성해야 합니다.
OnInitialized
이 메소드는 매개변수가 설정되기 전에 호출됩니다. 상위 요소로부터 초기 매개변수를 받은 후 구성 요소를 시작할 준비가 되면 호출됩니다.
비동기 버전을 OnInitializedAsync라고 합니다. 비동기 작업을 수행하고 해당 작업이 완료될 때 구성 요소를 새로 고치려면 OnInitializedAsync를 재정의하세요.
OnParametersSet
이 메소드는 매개변수가 설정된 후에 호출됩니다. 구성 요소가 상위 요소로부터 매개변수를 수신하고 수신 값이 속성에 할당되면 호출됩니다. 이 메소드는 매개변수가 업데이트될 때마다 실행됩니다. 비동기 버전을 OnParametersSetAsync라고 합니다.
OnAfterRender
이 메소드는 구성 요소의 렌더링이 완료된 후, 즉 HTML이 이미 표시된 후에 호출됩니다. 이 방법을 사용하면 렌더링된 DOM 요소를 사용하는 타사 JavaScript 라이브러리를 활성화하는 등 구성 요소 초기화에 필요한 추가 단계를 수행할 수 있습니다. 이 메서드는 구성 요소가 렌더링될 때마다 실행됩니다. 비동기 버전은 OnAfterRenderAsync로 알려져 있습니다.
StateHasChanged
이 메소드는 상태가 변경되었음을 구성 요소에 알리고 구성 요소를 다시 렌더링합니다. EventCallback 중에 이 메서드는 상위 구성 요소를 다시 렌더링하기 위해 자동으로 호출됩니다.
이 메소드를 호출하면 언제든지 구성요소를 렌더링할 수 있습니다. 그러나 StateHasChanged를 너무 많이 호출하면 애플리케이션에 불필요한 렌더링 비용이 추가될 수 있습니다.
예를 들어 이를 이해해 보자.
아래와 같이 기본 클래스 Lifecycle.razor.cs를 만들었습니다.
Microsoft.AspNetCore.Components 사용;
네임스페이스 BlazorTutorial.Client.Pages;
공용 클래스 LifecycleBase : ComponentBase { 공용 재정의 async 작업 SetParametersAsync(ParameterView 매개 변수){ Console.WriteLine("SetParametersAsync-start"); base.SetParametersAsync(매개변수)를 기다립니다; Console.WriteLine("SetParametersAsync-end"); }
protected 재정의 void OnInitialized() { Console.WriteLine("OnInitialized-start"); base.OnInitialized(); Console.WriteLine("OnInitialized-end"); }
protected 재정의 async 작업 OnInitializedAsync() { Console.WriteLine("OnInitializedAsync-start"); base.OnInitializedAsync()를 기다립니다. Console.WriteLine("OnInitializedAsync-end"); }
protected override void OnParametersSet() { Console.WriteLine("OnParametersSet-start"); base.OnParametersSet(); Console.WriteLine("OnParametersSet-end"); }
protected 재정의 async 작업 OnParametersSetAsync() {Console.WriteLine("OnParametersSetAsync-start"); base.OnParametersSetAsync()를 기다립니다. Console.WriteLine("OnParametersSetAsync-end"); }
보호 재정의 void OnAfterRender(bool firstRender) { Console.WriteLine("OnAfterRender({0})-start", firstRender); base.OnAfterRender(firstRender); Console.WriteLine("OnAfterRender({0})-end", firstRender); }
protected 재정의 비동기 작업 OnAfterRenderAsync(bool firstRender) { Console.WriteLine("OnAfterRenderAsync({0})-start", firstRender); base.OnAfterRenderAsync(firstRender)를 기다립니다. Console.WriteLine("OnAfterRenderAsync({0})-end", firstRender); } }
아래와 같이 면도기 구성 요소 Lifecycle.razor를 만들었습니다.
@page "/lifecycle"
@inherits WelcomeBase
<h1> Blazor 구성 요소 수명 주기 예</h1>
애플리케이션을 실행하고 라이프사이클 구성요소로 이동하면 아래와 같이 브라우저 콘솔에서 출력을 볼 수 있습니다.
이 출력은 Razor 구성 요소의 수명 주기 메서드 실행 순서를 보여줍니다.
Blazor 계단식 값 및 매개 변수
계단식 값과 매개변수를 사용하면 구성 요소의 데이터를 모든 하위 구성 요소로 전달할 수 있습니다. 구성 요소는 <CascadingValue> 구성 요소를 사용하여 계단식 값을 제공할 수 있습니다.
상위 구성 요소에서 제공하는 계단식 값을 활용하기 위해 하위 구성 요소는 [CascadingParameter] 특성을 사용하여 계단식 매개 변수를 선언할 수 있습니다.
계단식 값은 데이터 유형별로 계단식 매개변수에 바인딩됩니다. 동일한 유형의 여러 값을 계단식으로 배열하려는 경우 각 [CascadingParameter] 속성에 고유한 이름을 제공할 수 있습니다.
예를 들어 이를 이해해 보자.
아래와 같이 Child.razor 구성 요소를 만듭니다.
<h3>하위 구성요소</h3>
<p>숫자의 합은 @(num1 + num2)입니다.</p>
@코드 {
[CascadingParameter(이름 = "첫 번째 번호")]
공개 int num1 { 가져오기; 세트; }
[CascadingParameter(이름 = "두 번째 숫자")]
공개 int num2 { 가져오기; 세트; }
}
아래와 같이 구성 요소 Parent.razor를 만듭니다.
@page "/부모"
<h3>상위 구성요소</h3>
<CascadingValue Value="@number1" Name="FirstNumber" >
<CascadingValue Value="@number2" Name="두 번째 번호" >
<어린이></어린이>
</CascadingValue>
</CascadingValue>
@코드 {
정수번호1 = 5;
정수2 = 10;
}
Child 구성 요소를 호출하고 계단식 값을 전달했습니다. 하위 구성 요소는 Name 속성을 사용하여 매개 변수 값을 바인딩합니다.
구성 요소 계층 구조를 통해 데이터 전달
계단식 매개변수를 사용하여 구성요소 계층 전체에 걸쳐 데이터를 전달할 수 있습니다.
예를 들어 이를 이해해 보자.
아래와 같이 GrandChild.razor 구성 요소를 만듭니다.
<h3>손자 구성요소</h3>
<p>숫자의 곱은 @(num1 * num2)입니다.</p>
@코드 {
[CascadingParameter(이름 = "첫 번째 번호")]
공개 int num1 { 가져오기; 세트; }
[CascadingParameter(이름 = "두 번째 숫자")]
공개 int num2 { 가져오기; 세트; }
}
아래와 같이 Child.razor 구성 요소를 만듭니다.
<h3>하위 구성요소</h3>
<p>숫자의 합은 @(num1 + num2)입니다.</p>
<손자></손자>
@코드 {
[파라미터]
공개 int num1 { 가져오기; 세트; }
[파라미터]
공개 int num2 { 가져오기; 세트; }
}
@page "/부모"
<h3>상위 구성요소</h3>
<CascadingValue Value="10" Name="FirstNumber" >
<CascadingValue Value="5" Name="두 번째 번호" >
<어린이></어린이>
</CascadingValue>
</CascadingValue>
@코드 {
정수번호1 = 5;
정수2 = 10;
}
Parent 구성 요소에서 GrandChild 구성 요소로 계단식 값을 전달했습니다. 계단식 매개변수의 이름은 Child 및 GrandChild 구성요소 모두에서 동일합니다.
실행하면 아래와 같은 출력을 볼 수 있습니다.
Blazor 데이터 바인딩
단방향 데이터 바인딩
이를 통해 속성 값을 HTML DOM 요소에 바인딩할 수 있지만 그 반대는 불가능합니다. 속성이나 필드를 HTML 태그에 바인딩하려면 @ 기호가 앞에 붙은 속성 이름을 전달해야 합니다.
아래에 표시된 예를 살펴보십시오.
@page "/데이터바인딩"
<h3>단방향 데이터 바인딩</h3>
<p>@SampleText</p>
@코드 {
string SampleText = "단방향 데이터 바인딩을 설명하는 샘플 텍스트입니다.";
}
C# 필드 SampleText는 @ 기호를 사용하여 HTML DOM에 바인딩됩니다.
양방향 데이터 바인딩
이를 통해 속성이나 필드의 값을 HTML DOM 요소에 바인딩하거나 그 반대로 바인딩할 수 있습니다. @bind 속성을 사용하여 양방향 데이터 바인딩을 구현할 수 있습니다.
HTML 요소의 @bind:event="{EVENT}" 특성을 사용하여 DOM 이벤트에 C# 속성을 바인딩할 수 있습니다. 여기서 {EVENT}는 DOM 이벤트에 대한 자리 표시자입니다.
아래에 표시된 예를 살펴보십시오.
@page "/데이터바인딩"
<h3>양방향 데이터 바인딩</h3>
<div>
<span>이름 입력: </span>
<input type="text" @bind="이름" @bind:event="oninput" />
</div>
<br/>
<p>당신의 이름은: @Name</p>
@코드 {
문자열 이름 { get; 세트; }
}
입력 필드의 값은 Name 속성에 바인딩됩니다. 데이터 바인딩은 입력 필드의 oninput 이벤트가 트리거될 때, 즉 텍스트 상자의 값이 변경될 때 발생합니다.
NOTE:
속성 바인딩은 대소문자를 구분합니다. 즉, @bind, @bind:event는 유효하지만 @Bind, @Bind:EVENT 및 대문자를 사용하는 기타 구문은 유효하지 않습니다.
<select> 요소를 사용하여 여러 옵션 바인딩
다중 선택의 값을 배열 유형의 C# 속성에 바인딩할 수 있습니다.
아래에 표시된 예를 살펴보십시오.
@page "/데이터바인딩"
<p>
<라벨>
하루 이상의 요일을 선택하세요.
<select @onchange="SelectedDaysChanged" 다중 >
<option value="monday">월요일</option>
<option value="화요일">화요일</option>
<option value="wednesday">수요일</option>
<option value="목요일">목요일</option>
<option value="friday">금요일</option>
</select>
</label>
</p>
<p>
선택한 날짜: @string.Join(", ", SelectedDays)
</p>
@코드 {
공개 문자열[] SelectedDays { 가져오기; 세트; } = 새 문자열[] { };
무효 SelectedDaysChanged(ChangeEventArgs e)
{
if (e.값이 null이 아닙니다) {
SelectedDays = (string[])e.Value;
}
}
}
선택한 값은 <select> 요소의 @onchange 이벤트를 사용하여 문자열 배열에 바인딩됩니다.
형식이 지정된 문자열에 바인딩
데이터 바인딩은 @bind:format="{FORMAT STRING}" 구문을 사용하여 형식이 지정된 문자열과 함께 작동합니다.
형식화된 데이터 바인딩은 다음 .NET 유형에 대해 지원됩니다.
- 시스템.날짜시간
- System.DateTimeOffset
아래에 표시된 예를 살펴보십시오.
@page "/데이터바인딩"
<h3>형식화된 문자열</h3>
<div>
<span>샘플 날짜: </span>
<input @bind="SampleDate" @bind:format="dd-MM-yyyy" />
</div>
@코드 {
DateTime SampleDate { 가져오기; 세트; } = new DateTime(2023, 1, 14);
}
날짜는 @bind:format 속성을 사용하여 지정된 형식으로 표시됩니다.
get 및 set 접근자를 사용하여 사용자 정의 바인딩 형식을 지정할 수 있습니다.
아래에 표시된 예를 살펴보십시오.
@page "/데이터바인딩"
<input @bind="SalaryValue" />
<h3>형식화된 문자열</h3>
<p>
<code>decimalValue</code>: @salary
</p>
@코드 {
소수 급여 = 123456;
문자열 SalaryValue {
get => 급여.ToString("0.000");
세트 {
if (Decimal.TryParse(value, out var number)) {
급여 = Math.Round(숫자, 3);
}
}
}
}
문자열 속성 SalaryValue는 입력 요소와 함께 소수점 세 자리까지 바인딩됩니다.
구성요소 매개변수와 바인딩
하위 구성 요소의 속성을 상위 구성 요소의 속성에 바인딩할 수 있습니다. 데이터 바인딩은 여러 수준에서 발생하므로 이 시나리오를 체인 바인딩이라고 합니다.
@bind-{PROPERTY} 구문을 사용할 수 있습니다. 여기서 {PROPERTY}는 바인딩할 속성에 대한 자리 표시자입니다. 하위 구성 요소에서 상위 구성 요소의 속성 업데이트를 지원하려면 이벤트 핸들러와 값을 제공해야 합니다.
예를 들어 이를 이해해 보자.
아래와 같이 Child.razor 구성 요소를 만듭니다.
<h3>하위 구성요소</h3>
<p>하위 메시지: @Message</p>
<button @onclick="UpdateMessageFromChild">어린이의 메시지 업데이트</button>
@코드 {
[파라미터]
공개 문자열 메시지 { get; 세트; }
[파라미터]
공개 EventCallback <string> MessageChanged { 가져오기; 세트; }
개인 비동기 작업 UpdateMessageFromChild() {
wait MessageChanged.InvokeAsync("하위 구성 요소의 메시지");
}
}
문자열 유형의 구성요소 매개변수와 구성요소 매개변수와 동일한 유형의 EventCallback을 선언했습니다.
EventCallback의 이름은 {PARAMETER NAME}Changed 구문을 따라야 합니다. 여기서 {PARAMETER NAME}은 구성 요소 매개변수 이름에 대한 자리 표시자입니다. 다른 이름 지정 형식을 사용하면 런타임 오류가 발생합니다.
위에 표시된 예에서 구성 요소 매개 변수의 이름은 Message이고 EventCallback의 이름은 MessageChanged입니다.
아래와 같이 구성 요소 Parent.razor를 만듭니다.
@page "/부모"
<h3>상위 구성요소</h3>
<Child @bind-Message="MesssageFromParent"></Child>
<button @onclick="UpdateMessageFromChild">어린이의 메시지 업데이트</button>
@코드 {
string MesssageFromParent = "상위 구성 요소의 메시지";
}
C# 속성 MesssageFromParent는 Child 구성 요소의 Message 매개 변수에 바인딩됩니다. Child 구성 요소의 Message 매개 변수에는 Message 매개 변수와 동일한 유형의 MessageChanged 이벤트가 함께 포함되어 있으므로 바인딩할 수 있습니다.
실행하면 아래와 같은 출력을 볼 수 있습니다.
버튼을 클릭하자마자 아래 이미지와 같이 메시지가 업데이트됩니다.
Blazor 이벤트 처리
@on{EVENT}라는 이름의 HTML 속성을 추가하고 위임 유형 값을 갖습니다. 이 특성의 값은 Blazor 구성 요소에 의해 이벤트 처리기로 처리됩니다.
Blazor에서 지원하는 일부 이벤트 처리기에는 @onclick, @onchange, @onselect, @onfocus, @onkeyup 등이 있습니다.
본보기:
<button @onclick="ButtonClicked">나를 클릭하세요</button>
@코드 {
무효 ButtonClicked() {
Console.WriteLine("버튼을 클릭했습니다.");
}
}
ButtonClicked 메서드는 버튼을 클릭할 때 호출됩니다.
비동기 이벤트 처리
아래에 표시된 예를 살펴보십시오.
<button @onclick="ButtonClicked">나를 클릭하세요</button>
@코드 {
비동기 작업 ButtonClicked() {
Task.Delay(1000)를 기다립니다;
Console.WriteLine("버튼을 클릭했습니다.");
}
}
ButtonClicked 메서드는 버튼을 클릭할 때 비동기적으로 호출됩니다.
이벤트 인수 사용
아래에 표시된 예를 살펴보십시오.
<select class="form-control col-md-4" @onchange="SelectGender" />
<option value="">-- 성별 선택 --</option>
<option value="남성">남성</option>
<option value="Famale">Famale</option>
</select>
@코드 {
protected string 성별 { get; 세트; }
protected void SelectGender(ChangeEventArgs e) {
성별 = e.Value.ToString();
}
}
SelectGender 메서드를 select 요소의 onchange 이벤트에 바인딩했습니다.
이벤트 메서드 정의에서 이벤트 인수를 지정하는 것은 선택 사항입니다. 이벤트 인수가 메서드에 사용되는 경우에만 필수입니다.
이벤트 처리를 위해 람다 표현식 사용
람다 식을 사용하여 이벤트 속성에 대한 익명 함수를 만들 수 있습니다.
아래에 표시된 예를 살펴보십시오.
@for (int i = 1; i < 4; i++) {
int textboxNumber = i;
<p>
<input> @onfocus="@(() => FocusTextbox(textboxNumber))" />
</p>
}
@코드 {
protected string 성별 { get; 세트; }
protected void FocusTextbox(int textboxNumber) {
Console.WriteLine($"텍스트 상자 번호 {textboxNumber}을(를) 선택했습니다.");
}
}
for 루프를 사용하여 세 개의 텍스트 상자 컨트롤을 만들었습니다. 람다 식을 사용하여 각 텍스트 상자의 onfocus 이벤트에 대해 FocusTextbox 메서드를 호출했습니다.
EventCallback
EventCallback을 사용하여 여러 구성 요소에 걸쳐 이벤트를 노출할 수 있습니다. 이는 하위 구성 요소에서 이벤트가 발생할 때 상위 구성 요소의 메서드를 호출하는 데 도움이 됩니다.
EventCallback<TValue> 구문을 사용하여 이벤트 매개 변수를 지정하면 EventCallback을 강력하게 입력할 수 있습니다.
예: EventCallback<MouseEventArgs>
예제를 통해 EventCallback을 이해해 보겠습니다.
아래와 같이 Child.razor 구성 요소를 만듭니다.
<h3>하위 구성요소</h3>
<button class="btn btn-primary" @onclick="ChildClick">
상위 구성요소 메소드 호출
</버튼>
@코드 {
[파라미터]
공개 EventCallback ChildClick { get; 세트; }
}
아래와 같이 다른 구성 요소 Parent.razor를 만듭니다.
<h3>상위 구성요소</h3>
<Child ChildClick="ChildClickHandler"> </Child>
<p><strong> @메시지 </strong></p>
@코드 {
문자열 메시지 { 가져오기; 세트; }
무효 ChildClickHandler() {
message = "하위 이벤트가 발생했습니다";
}
}
하위 구성 요소에 EventCallback 매개 변수를 만들었습니다. 버튼의 onclick 이벤트 핸들러는 ParentComponent로부터 EventCallback 대리자를 수신하도록 설정됩니다.
ParentComponent는 자식 구성 요소의 EventCallback인 ChildClick을 ChildClickHandler 메서드로 설정합니다.
하위 구성 요소의 버튼을 클릭하면 상위 구성 요소의 ChildClickHandler 메서드가 호출됩니다. 문자열 속성 메시지가 업데이트되어 ParentComponent에 표시됩니다.
기본 작업 방지
@on{DOM EVENT}:preventDefault 지시어 속성을 사용하여 이벤트의 기본 동작을 방지할 수 있습니다. 이 속성은 부울 값을 인수로 허용합니다. 인수를 지정하지 않으면 기본값인 true가 고려됩니다.
아래에 표시된 예를 살펴보십시오.
<input value="@name" @onkeydown="KeyDownHandler" @onkeydown:preventDefault />
@코드 {
개인 문자열 이름 { get; 세트; }
개인 무효 KeyDownHandler(KeyboardEventArgs e) {
// 뭔가를 해라
}
}
부울 속성은 속성에 바인딩될 수 있으므로 사용자의 요구 사항에 따라 이벤트 전파를 제어할 수 있습니다.
아래에 표시된 예를 살펴보십시오.
<input @onkeydown="KeyDownHandler" @onkeydown:preventDefault="shouldPreventDefault" />
@코드 {
개인 bool shouldPreventDefault = true;
}
이벤트 전파 중지
HTML 요소가 이벤트를 상위 요소에 전파하는 경우도 있습니다.
Blazor 사용하면 @on{DOM EVENT}:stopPropagation 지시문 특성을 사용하여 이벤트 전파를 중지할 수 있습니다. 이 속성은 부울 값을 인수로 허용합니다. 인수를 지정하지 않으면 기본값인 true가 고려됩니다.
아래에 표시된 예를 살펴보십시오.
<button @onclick:stopPropagation>클릭</button>
부울 속성은 속성에 바인딩될 수 있으므로 사용자의 요구 사항에 따라 이벤트 전파를 제어할 수 있습니다.
<button @onclick:stopPropagation="shouldStopPropagation">클릭</button>
@코드 {
개인 bool shouldStopPropagation = true;
}
라우팅 및 내비게이션
App.razor 파일에 사용되는 Router 구성 요소를 사용하면 Blazor 애플리케이션의 구성 요소로 라우팅할 수 있습니다.
Blazor 애플리케이션을 만들 때 App.razor 파일에는 아래와 같은 코드가 포함됩니다.
<Router AppAssembly="@typeof(App).Assembly >
<찾은 컨텍스트="routeData" >
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" / >
<FocusOnNavigate RouteData="@routeData" Selector="h1" / >
</발견>
<찾을 수 없음>
<PageTitle>찾을 수 없음</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert"> 죄송합니다. 이 주소에는 아무것도 없습니다.</p>
</LayoutView>
</NotFound>
</라우터>
라우터 구성 요소는 현재 탐색 상태에 해당하는 경로 데이터를 제공하는 데 사용됩니다. FocusOnNavigate 구성 요소는 사용자가 한 구성 요소에서 다른 구성 요소로 이동할 때 CSS 선택기와 일치하는 요소에 포커스를 설정하는 데 사용됩니다. 이를 통해 화면 판독기와 호환되는 액세스 가능한 라우팅 메커니즘을 만들 수 있습니다.
NotFound 속성은 요청된 경로에서 데이터를 찾을 수 없을 때 사용자 지정 콘텐츠를 표시하는 데 사용됩니다.
@page 지시문을 사용하여 Razor 구성 요소의 경로를 정의할 수 있습니다. 단일 구성 요소에 대해 여러 개의 고유한 @page 지시문을 사용할 수도 있습니다.
아래에 표시된 예를 살펴보십시오.
@page "/route1"
@page "/홈/경로1"
<h1>이 구성요소는 여러 경로를 통해 액세스할 수 있습니다.</h1>
서로 다른 두 구성 요소에 대해 동일한 경로를 설정할 수 없습니다. 그렇게 하면 런타임 오류가 발생합니다.
경로 매개변수
동일한 이름으로 구성요소 매개변수를 채우는 데 사용할 수 있는 경로 매개변수를 정의할 수 있습니다. 경로에는 여러 매개변수가 있을 수 있습니다.
아래에 표시된 예를 살펴보십시오.
@page "/home/{이름}/{메시지}"
<h1>안녕하세요 @이름</h1>
<h3>@메시지</h3>
@코드 {
[파라미터]
공개 문자열 이름 { get; 세트; }
[파라미터]
공개 문자열 메시지 { get; 세트; }
}
구성 요소의 경로 매개 변수 속성은 공개로 정의되어야 합니다. 다른 액세스 한정자를 사용하면 컴파일 시간 오류가 발생합니다.
경로 매개변수 이름은 대소문자를 구분하지 않습니다. 즉, 아래와 같이 경로 매개변수를 사용할 수 있습니다.
@page "/home/{이름}/{메시지}"
<h1>안녕하세요 @NAME</h1>
<h3>@메시지</h3>
@코드 {
[파라미터]
공개 문자열 NAME { 가져오기; 세트; }
[파라미터]
공개 문자열 MESSAGE { 가져오기; 세트; }
}
Blazor 선택적 경로 매개 변수도 지원합니다. 경로 매개변수를 선택사항으로 표시하려면 해당 매개변수에 ? 상징.
아래에 표시된 예를 살펴보십시오.
@page "/home/{이름}/{메시지?}"
<h1>안녕하세요 @이름</h1>
<h3>@메시지</h3>
@코드 {
[파라미터]
공개 문자열 이름 { get; 세트; }
[파라미터]
공개 문자열 메시지 { get; 세트; }
}
하나 이상의 선택적 매개변수를 가질 수 있습니다.
다음 경로가 유효합니다.
@page "/home/{이름}/{메시지?}/{텍스트?}"
선택적 매개변수 뒤에는 선택적 매개변수가 아닌 매개변수가 나타날 수 없습니다. 선택적 매개변수 뒤에 선택적 매개변수가 아닌 매개변수를 추가하면 런타임 오류가 발생합니다.
다음 경로는 유효하지 않습니다.
@page "/home/{이름?}/{메시지}"
경로 제약
경로 제약 조건을 사용하여 경로에서 유형 일치를 적용할 수 있습니다.
아래에 표시된 예를 살펴보십시오.
@page "/home/{name}/{userID:int}/{isAdmin:bool}"
<h1>안녕하세요 @이름</h1>
<h3>사용자 ID: @userID</h3>
<h3>isAdmin: @isAdmin</h3>
@코드 {
[파라미터]
공개 문자열 이름 { get; 세트; }
[파라미터]
공개 int 사용자 ID { 가져오기; 세트; }
[파라미터]
공개 부울 isAdmin { get; 세트; }
}
다음 기준이 충족되면 이 구성 요소의 경로가 일치합니다.
- 경로에는 name 매개변수 값이 있어야 합니다.
- 경로에는 userID 매개변수 값이 있어야 하며 int 유형이어야 합니다.
- 경로에는 isAdmin 매개변수 값이 있어야 하며 bool 유형이어야 합니다.
이 패턴과 일치하는 경로의 예는 "/home/John/1234/true"입니다.
선택적 매개변수와 함께 경로 제약조건을 사용할 수도 있습니다.
예:
@page "/home/{name}/{userID:int}/{isAdmin:bool?}"
NavigationManager
NavigationManager 클래스를 사용하여 C# 코드를 통한 탐색을 처리할 수 있습니다. 이 클래스는 구성 요소의 경로를 매개 변수로 받아들이고 사용자를 한 구성 요소에서 다른 구성 요소로 리디렉션하는 NavigateTo 메서드를 제공합니다.
예를 들어 이를 이해해 보자.
아래와 같이 기본 클래스 Routing.razor.cs를 만들었습니다.
Microsoft.AspNetCore.Components 사용;
네임스페이스 BlazorWasmDemo.Client.Pages;
공용 클래스 RoutingBase : ComponentBase { [삽입] 공용 NavigationManager NavigationManager { 가져오기; 세트; }
[파라미터] 공개 문자열 이름 { get; 세트; }
protected void NavigateAway() { NavigationManager.NavigateTo("parent/1234"); } }
Routing.razor 구성 요소에 다음 코드를 추가합니다.
@page "/집/{이름}"
@inherits RoutingBase
<h1>안녕하세요 @이름</h1>
<button @onclick="NavigateAway" >다른 곳으로 이동</button>
버튼을 클릭하면 NavigateAway 메서드가 호출됩니다. 사용자를 "/parent/1234" 경로로 리디렉션합니다.
NavigateTo 메소드는 선택적 부울 매개변수인 forceLoad를 허용합니다. 이 매개변수에 참값을 전달하면 브라우저는 서버에서 새 페이지를 다시 로드합니다.
포괄 경로 매개변수
포괄 경로 매개변수는 라우팅 매개변수가 명시적으로 정의되지 않은 경우 다양한 경로를 처리하는 데 사용될 수 있습니다.
아래에 표시된 예제 구성요소를 살펴보세요.
@page "/home/{*routeParams}"
@코드 {
[파라미터]
공개 문자열? RouteParams { 가져오기; 세트; }
}
이 구성 요소의 경우 다음 경로가 유효합니다.
- /집/존
- /집/123
- /홈/존/123/345/USA/true
포괄 경로 매개변수는 다음 기준을 따라야 합니다.
- 동일한 이름을 가진 해당 구성요소 매개변수가 있어야 합니다. 이름은 대소문자를 구분하지 않습니다.
- 문자열 유형이어야 합니다. 우리는 그들에 대한 경로 제약을 사용할 수 없습니다.
- URL 끝에 있어야 합니다.
NavLink 구성요소
탐색 링크를 만드는 동안 HTML의 <a> 속성 대신 NavLink 구성 요소를 사용할 수 있습니다. 현재 URL이 href 속성과 일치하는지 여부에 따라 활성 CSS 클래스를 전환합니다. 이는 사용자가 사용 가능한 모든 탐색 링크 중에서 어떤 페이지가 활성화되어 있는지 이해하는 데 도움이 됩니다.
예:
<NavLink class="nav-link" href="" Match="NavLinkMatch.All" >
<span class="oi oi-home" aria-hidden="true"></span> 홈
</NavLink>
NavLink 구성 요소의 Match 속성에는 두 가지 가능한 값이 있을 수 있습니다.
- NavLinkMatch.All: NavLink는 전체 현재 URL과 일치하는 경우에만 활성화되어야 합니다.
- NavLinkMatch.Prefix: NavLink는 현재 URL의 접두사와 일치하는 경우에만 활성화되어야 합니다. 이것이 기본값입니다.
쿼리 문자열
[Parameter] 특성과 함께 [SupplyParameterFromQuery] 특성을 사용하여 구성 요소 매개 변수가 경로의 쿼리 문자열을 통해 제공될 수 있도록 지정할 수 있습니다.
@page "/영화"
<p>@이름</p>
<p>@장르</p>
@코드 {
[파라미터]
[공급매개변수FromQuery]
공개 문자열? 이름 {얻다; 세트; }
[파라미터]
[공급매개변수FromQuery]
공개 문자열? 장르 {얻다; 세트; }
}
이 구성 요소의 유효한 경로는 "/movie?name=avatar&genre=science%20fiction"입니다. Name 속성을 사용하여 쿼리 매개 변수의 이름을 지정할 수 있습니다.
예:
[파라미터]
[SupplyParameterFromQuery(이름="범주")]
공개 문자열? 장르 {얻다; 세트; }
이 경우 유효한 경로는 "/movie?name=avatar&category =science%20fiction"입니다.
구성요소의 쿼리 매개변수는 다음 데이터 유형을 지원합니다.
- 부울
- 날짜 시간
- 소수
- 더블
- 뜨다
- 가이드
- 정수
- 긴
- 끈
NavigationManager 클래스의 GetUriWithQueryParameter 메서드를 사용하여 현재 URL에서 하나 이상의 쿼리 매개변수를 추가, 업데이트 또는 삭제할 수 있습니다.
이 메서드의 구문은 GetUriWithQueryParameter("{NAME}", {VALUE})입니다. 여기서 {NAME}은 쿼리 매개 변수 이름에 대한 자리 표시자이고 {VALUE}는 쿼리 매개 변수 값에 대한 자리 표시자입니다. 이 메서드는 문자열 값을 반환합니다.
쿼리 매개변수가 현재 URI에 이미 존재하는 경우 이 메서드는 값을 업데이트합니다. 쿼리 매개변수가 현재 URI에 없으면 이 메소드는 지정된 값을 가진 새 매개변수를 추가합니다.
예:
@page "/영화"
@inject NavigationManager 탐색
<p>@이름</p>
<p>@장르</p>
<button @onclick="UpdateCurrentURI">URI 업데이트</button>
<p>NewURI: @NewURI</p>
<button @onclick="NavigateToNewURI">새 URI로 이동</button>
@코드 {
문자열 NewURI { 가져오기; 세트; }
[파라미터]
[공급매개변수FromQuery]
공개 문자열? 이름 {얻다; 세트; }
[파라미터]
[SupplyParameterFromQuery(이름 = "범주")]
공개 문자열? 장르 {얻다; 세트; }
무효 UpdateCurrentURI() {
NewURI = Navigation.GetUriWithQueryParameter("name", "Top Gun");
}
무효 NavigateToNewURI() {
Navigation.NavigateTo(NewURI);
}
}
버튼을 클릭하면 쿼리 매개변수 “name”의 값이 업데이트됩니다.
URI에 새 쿼리 매개변수를 추가하려면 아래와 같이 코드를 업데이트할 수 있습니다.
NewURI = Navigation.GetUriWithQueryParameter("언어", "영어");
URI에서 기존 쿼리 매개변수를 제거하려면 아래와 같이 값을 null로 설정할 수 있습니다.
NewURI = Navigation.GetUriWithQueryParameter("이름", (문자열?)null);
GetUriWithQueryParameters 메서드를 사용하여 URI에서 여러 매개 변수를 동시에 추가, 업데이트 및 제거할 수 있습니다.
아래에 표시된 예를 살펴보십시오.
NewURI = Navigation.GetUriWithQueryParameters(new Dictionary<string, object?>
{
["name"] = "탑건",
["category"] = "작업",
["언어"] = "영어",
});
그러면 기존 쿼리 매개변수인 이름 및 카테고리가 업데이트되고 값이 영어로 설정된 언어인 새 쿼리 매개변수가 추가됩니다.
Blazor 레이아웃
레이아웃은 탐색 메뉴, 머리글, 바닥글 등과 같은 여러 구성 요소에 공통되는 UI 기능을 포함하는 Blazor 구성 요소입니다. 기본 앱 레이아웃은 App.razor 파일 내의 Router 구성 요소에 정의됩니다.
@page 지시문이 있는 라우팅 가능한 Razor 구성 요소에 대해서만 레이아웃을 사용할 수 있습니다. 기본 앱 레이아웃은 App.razor 파일 내의 Router 구성 요소에 정의되어 있습니다.
@page 지시문이 있는 라우팅 가능한 구성 요소의 레이아웃을 지정하기 위해 @layout 지시문을 사용할 수 있습니다. 구성 요소에서 직접 레이아웃을 지정하면 라우터 구성 요소에 설정된 기본 앱 레이아웃이 재정의됩니다.
아래에 표시된 예를 살펴보십시오.
@layout CustomLayout
@page "/layout-demo"
<h1>맞춤 레이아웃 데모</h1>
Blazor 레이아웃 중첩을 지원합니다. 구성 요소는 레이아웃을 참조할 수 있으며, 이는 다시 다른 레이아웃을 참조합니다. 이는 다단계 메뉴 구조를 만드는 데 도움이 될 수 있습니다.
사용자 정의 레이아웃 구성 요소 만들기
구성 요소가 레이아웃 구성 요소로 작동하려면 다음 두 가지 기준을 충족해야 합니다.
- LayoutComponentBase 클래스에서 상속되어야 합니다. 이 클래스는 레이아웃 내부의 콘텐츠를 렌더링하는 데 사용되는 Body 속성을 정의합니다.
- 본문 콘텐츠를 렌더링해야 하는 위치를 지정하려면 위치를 정의해야 합니다. 이는 Razor 구문 @Body를 사용하여 수행됩니다.
아래에 표시된 예를 살펴보십시오.
@inherits LayoutComponentBase
<헤더>
<h1> Blazor 튜토리얼에 오신 것을 환영합니다</h1>
</header>
@몸
<바닥글>
<h1>모든 권리 보유</h1>
</footer>
의존성 주입
DI(의존성 주입)는 클래스와 해당 종속성 간의 IoC(Inversion of Control)를 달성하는 데 도움이 되는 소프트웨어 디자인 패턴입니다.
프레임워크에 등록된 서비스를 Blazor 구성 요소에 직접 주입할 수 있습니다. DI를 통해 사용할 수 있도록 하려면 사용자 지정 서비스를 Blazor 앱에 등록해야 합니다.
서비스 수명
Blazor 서비스는 다음 세 가지 수명으로 구성될 수 있습니다.
- 싱글톤: 모든 구성 요소에서 공유되는 서비스의 단일 인스턴스를 만듭니다.
- 일시적: 구성 요소가 서비스를 요청할 때마다 서비스의 새 인스턴스를 만듭니다.
- 범위 지정: 웹 요청당 하나의 서비스 인스턴스를 생성합니다.
- Blazor WebAssembly 앱은 범위 지정 수명을 지원하지 않습니다. 범위가 등록된 서비스는 Blazor WebAssembly 앱에 대한 싱글톤 서비스처럼 작동합니다.
- Blazor 서버 앱은 HTTP 요청 전체에서 범위 지정 수명을 지원하지만 클라이언트 측에 로드되는 구성 요소 간의 SignalR 연결 메시지 전체에서는 지원하지 않습니다.
기본 Blazor 서비스
다음 표에 표시된 서비스는 Blazor 앱에서 자주 사용됩니다.
서비스 | Blazor Wasm 수명 | Blazor 서버 수명 | 설명 |
---|---|---|---|
HttpClient | 범위가 지정됨 | 범위가 지정됨 | 리소스 URL의 HTTP 요청 및 응답을 처리하는 방법을 제공합니다. |
IJSRuntime | 하나씩 일어나는 것 | 범위가 지정됨 | JavaScript 호출이 전달되는 JavaScript 런타임의 인스턴스를 나타냅니다. |
NavigationManager | 하나씩 일어나는 것 | 범위가 지정됨 | URI 탐색을 쿼리하고 관리하기 위한 도우미 클래스를 제공합니다. |
Blazor WASM 앱에 서비스 추가
Program.cs 파일을 사용하여 Blazor Wasm 앱과 Blazor Server 앱 모두에 대한 사용자 지정 서비스를 등록할 수 있습니다.
Blazor Wasm 앱에 대한 Program.cs 파일의 코드 샘플을 살펴보세요.
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
await builder.Build().RunAsync();
Blazor Server 앱에 대한 Program.cs 파일의 코드 샘플을 살펴보세요.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
var app = builder.Build();
app.UseRouting();
app.Run();
Blazor 구성 요소에 서비스 주입
다음 두 가지 방법을 사용하여 구성 요소에 서비스를 주입할 수 있습니다.
- 기본 클래스의 [Inject] 속성을 사용합니다.
- 구성 요소에서 @inject 지시문을 사용합니다.
단일 구성 요소에 여러 서비스를 주입할 수 있습니다.
Razor 구성 요소에 대해 아래에 표시된 예를 살펴보세요.
@page "/영화"
@inject NavigationManager 탐색
<button @onclick="NavigateToPage">페이지로 이동</button>
@코드 {
무효 NavigateToPage()
{
Navigation.NavigateTo("/홈");
}
}
기본 클래스에 대해 아래 표시된 예를 살펴보십시오.
Microsoft.AspNetCore.Components 사용;
네임스페이스 BlazorWasmDemo.Client.Pages
{ 공개 클래스 RoutingBase : ComponentBase { [삽입] 공개 NavigationManager NavigationManager { 가져오기; 세트; } = 기본값!;
[주입] HttpClient Http { get; 세트; } = 기본값!;} }
주입된 서비스는 구성 요소가 초기화되면 사용할 수 있을 것으로 예상됩니다. 따라서 null 허용 연산자(기본값!)를 사용하여 기본 리터럴을 할당했습니다. Null이 아닌 기본값을 할당하지 않으면 컴파일러는 "생성자를 종료할 때 Null을 허용하지 않는 속성에 Null이 아닌 값이 포함되어야 합니다"라는 경고 메시지를 표시합니다. 또는 .NET SDK 버전 7 이상을 사용하면 C#11에서 추가된 "필수" 한정자를 사용하여 null 허용 연산자를 사용하지 않고 다음을 작성할 수 있습니다.
[삽입] 공개 필수 NavigationManager NavigationManager { get; 세트; }
Blazor 서비스에서 종속성 주입을 사용합니다.
생성자 주입을 사용하여 서비스를 다른 서비스에 주입할 수 있습니다. [Inject] 속성이나 @inject 지시문은 서비스 클래스에서 사용할 수 없습니다.
아래에 표시된 예를 살펴보십시오.
공개 클래스 MyCustomService
{ 개인 읽기 전용 HttpClient _httpClient;개인 읽기 전용 HttpClient _httpClient; 공개 MyCustomService(HttpClient httpClient, NavigationManager NavigationManager) { _httpClient = httpClient; _navigationManager = 네비게이션매니저; } }
자바스크립트 상호운용성
JavaScript 상호 운용성(JavaScript interop)은 .NET 메서드에서 JavaScript 함수를 호출하고 JavaScript 함수에서 .NET 메서드를 호출하는 기능으로 정의됩니다.
.NET 메서드에서 JavaScript 함수 호출
IJSRuntime 추상화를 사용하여 .NET에서 JavaScript 함수를 호출할 수 있습니다.
IJSRuntime 인터페이스는 두 가지 방법을 제공합니다.
- InvokeAsync: Promise를 포함하여 모든 값이나 객체를 반환하는 JavaScript 함수를 호출하는 데 사용됩니다.
- InvokeVoidAsync: void 또는 정의되지 않음을 반환하는 JavaScript 함수를 호출하는 데 사용됩니다.
Blazor WebAssembly 앱의 wwwroot/index.html에 사용자 지정 JavaScript 코드를 추가할 수 있습니다. Blazor WebAssembly 앱의 Pages/_Host.cshtml에 사용자 지정 JavaScript 코드를 추가할 수 있습니다.
예를 들어 이것을 이해해 봅시다.
<스크립트>
window.getArraySum = (numberArray) => {
return numberArray.reduce((a, b) => a + b, 0);
}
</script>
getArraySum 함수는 배열을 매개변수로 받아들이고 배열의 모든 요소의 합계를 반환합니다.
JSDemoBase.razor 구성 요소를 만들고 기본 클래스 JSDemoBase.razor.cs에 다음 코드를 추가합니다.
Microsoft.AspNetCore.Components 사용;
Microsoft.JSInterop 사용;
네임스페이스 BlazorWasmDemo.Client.Pages;
공개 클래스 JSDemoBase : ComponentBase
{ [삽입] 보호된 IJSRuntime JSRuntime { get; 세트; } = 기본값!;
protected int sumOfArray = 0;
private int[] arrayItems = new int[] { 2, 4, 6, 8, 10 };
protected async 작업 GetSumOfArray(){ sumOfArray = wait JSRuntime.InvokeAsync<int>("getArraySum", arrayItems); } }
InvokeAsync 메서드를 사용하여 JS 함수를 호출하겠습니다. JS 함수는 합계를 반환하고 정수 변수 sumOfArray에 할당됩니다.
이 GetSumOfArray 메서드는 아래와 같이 버튼 클릭 시 호출될 수 있습니다.
@page "/calljsmethod"
@inherits JSDemoBase
<button @onclick="GetSumOfArray">배열 합계 가져오기</button>
<p>배열 요소의 합계는 다음과 같습니다: @sumOfArray</p>
JavaScript의 내장 메소드를 호출하려면 다음 코드를 사용할 수 있습니다.
보호된 비동기 작업 ShowAlert()
{ wait JSRuntime.InvokeVoidAsync("alert", ".NET 코드에서 호출되었습니다."); }
보호된 비동기 작업 ShowArrayItems()
{ JSRuntime.InvokeVoidAsync("console.table", arrayItems)를 기다립니다. }
우리는 경고 함수를 호출하고 여기에 문자열 매개변수를 전달했습니다. ShowArrayItems 메서드는 JavaScript의 console.table 함수를 호출하고 입력으로 표시할 arrayItems를 전달합니다.
HTML 요소에 대한 참조 캡처
ElementReference 구조체를 사용하여 구성 요소의 HTML 요소에 대한 참조를 캡처할 수 있습니다. 렌더링된 요소에 대한 참조를 나타내는 데 사용됩니다.
구성 요소의 HTML 요소에 대한 참조를 캡처하려면 HTML 요소에 @ref 특성을 추가해야 합니다. 또한 이름이 @ref 속성의 값과 일치하는 ElementReference 유형의 필드를 정의하십시오.
JS interop을 통해 ElementReference를 JS 코드에 전달할 수 있습니다. JS 코드는 DOM 조작에 사용할 수 있는 HTMLElement 인스턴스를 수신합니다.
예를 들어 이것을 이해해 봅시다.
다음 JS 코드를 추가합니다.
<스크립트>
window.showValue = (요소) => {
Alert('당신의 이름은 :' + element.value);
}
</script>
이 함수는 HTML 요소의 참조를 수신하고 경고 상자에 값을 표시합니다.
이 함수를 호출하려면 기본 클래스에 다음 코드를 추가할 수 있습니다.
보호된 ElementReference 이름;
보호된 비동기 작업 ShowName()
{ JSRuntime.InvokeVoidAsync("showValue", 이름)를 기다리고 있습니다. }
아래 코드와 같이 HTML 요소의 @ref 속성을 사용하여 ElementReference 인스턴스를 캡처할 수 있습니다.
<button class="btn btn-primary" @onclick="ShowName">이름 표시</button>
<input type="text" @ref="name" class="form-control" placeholder="이름을 입력하세요" />
JavaScript 함수에서 정적 .NET 메서드 호출
DotNet.invokeMethod 또는 DotNet.invokeMethodAsync 함수를 사용하여 JS에서 정적 .NET 메서드를 호출할 수 있습니다.
.NET 메서드는 다음 기준을 충족해야 합니다.
- 공개 및 정적으로 선언되어야 합니다.
- [JSInvokable] 속성으로 장식되어야 합니다.
정적 메서드의 식별자, C# 메서드가 포함된 어셈블리 이름 및 필요한 인수를 전달할 수 있습니다.
함수의 구문은 다음과 같습니다 - DotNet.invokeMethodAsync('{ASSEMBLY NAME}', '{.NET METHOD Name}', {ARGUMENTS});
어디,
- {ASSEMBLY NAME}은 애플리케이션 어셈블리 이름에 대한 자리 표시자입니다.
- {.NET METHOD 이름}은 호출할 .NET 메서드에 대한 자리 표시자입니다.
- {ARGUMENTS}는 호출할 .Net 메서드에 필요한 인수에 대한 자리 표시자입니다. 이는 선택적 매개변수입니다.
예를 들어 이것을 이해해 봅시다.
JSDemoBase.razor.cs 파일에 다음 코드를 추가합니다.
Microsoft.AspNetCore.Components 사용;
Microsoft.JSInterop 사용;
네임스페이스 BlazorTutorial.Client.Pages;
공개 클래스 JSDemoBase: ComponentBase
{ [삽입] 보호된 IJSRuntime JSRuntime { get; 세트; } = 기본값!;
protected void InvokeJSMethod() { JSRuntime.InvokeVoidAsync("printMessageToConsole"); }
[JSInvokable] public static Task<string> PrintMessage() { return Task.FromResult("JavaScript에서 호출되었습니다."); }}
InvokeJSMethod는 JS 함수인 printMessageToConsole을 호출합니다. PrintMessage 메소드에는 [JSInvokable] 속성이 있습니다. 이 메서드는 public 및 static으로 선언됩니다. 이렇게 하면 JS 함수 printMessageToConsole이 PrintMessage 메서드를 호출할 수 있습니다.
아래와 같이 JSDemoBase.razor 파일에 버튼을 추가합니다.
<button @onclick="InvokeJSMethod">정적 .NET 메서드 호출</button>
다음 JS 코드를 추가합니다.
<스크립트>
window.printMessageToConsole = () => {
DotNet.invokeMethodAsync(BlazorTutorial.Client', 'PrintMessage')
.then(데이터 => {
console.log(데이터);
});
}
</script>
JS 함수인 printMessageToConsole을 만들었습니다. DotNet.invokeMethodAsync 함수를 사용하여 C# 메서드인 PrintMessage를 호출합니다. 어셈블리 이름을 BlazorTutorial.Client로 전달했습니다.
구성 요소 인스턴스 메서드 호출
다음 단계를 사용하여 Blazor 구성 요소의 .NET 인스턴스 메서드를 호출할 수 있습니다.
- DotNetObjectReference.Create를 사용하여 JavaScript 함수에 전달할 수 있는 .NET 개체 참조를 생성합니다.
- .NET 개체의 InvokeMethod 또는 InvokeMethodAsync 메서드를 사용하여 구성 요소에 대한 인스턴스 메서드 호출을 수행합니다.
- 구성 요소가 삭제될 때 .NET 개체 참조도 삭제되는지 확인하세요.
예를 들어 이것을 이해해 봅시다.
다음 JS 코드를 추가합니다.
function displayMessageCallerJS(objectRef, value) {
objectRef.invokeMethodAsync('DisplayMessage', value);
}
objectRef와 value라는 두 개의 매개변수를 허용하는 displayMessageCallerJS 함수를 추가했습니다. 그런 다음 이 함수는 objectRef가 참조하는 구성 요소 개체의 DisplayMessage 메서드를 호출하고 값을 인수로 전달합니다.
JSDemoBase.razor.cs 파일에 다음 코드를 추가합니다.
공개 클래스 JSDemoBase: ComponentBase, IDisposable
{
개인 DotnetObjectReference<JSDemoBase>? objectRef;
protected string message = "버튼을 클릭하세요.";
보호된 재정의 무효 OnInitialized()
{
objectRef = DotNetObjectReference.Create(this);
}
[JSInvokable]
공개 무효 DisplayMessage(문자열 값)
{
메시지 = 값;
StateHasChanged();
}
공공 무효 처리()
{
objectRef?.Dispose();
}
}
.NET 개체의 참조를 나타내는 DotNetObjectReference<JSDemoBase> 유형의 필드 변수 objectRef를 선언했습니다. OnInitialized 수명 주기 메서드 내에서 DotNetObjectReference.Create 정적 메서드를 사용하여 이 구성 요소 자체의 참조를 생성하고 이를 objectRef 필드에 할당합니다.
InvokeDisplayMessageCallerJS 메서드는 문자열 매개 변수를 허용합니다. 그런 다음 이 메서드는 JS 함수인 displayMessageCallerJS를 호출하고 이 구성 요소를 참조하는 .NET 개체 참조 필드를 첫 번째 인수로 전달하고 문자열 매개 변수를 두 번째 인수로 전달합니다.
[JSInvokable] 속성이 있고 문자열 매개 변수를 허용하는 공개 인스턴스 메서드인 DisplayMessage를 만들었습니다. 이 인스턴스 메소드는 JS 함수 displayMessageCallerJS에서 호출됩니다. 메시지 필드에 매개변수 값을 할당한 다음 StateHasChanged() 메서드를 호출하여 구성 요소에 상태 변경을 알립니다.
마지막으로 IDisposable 인터페이스를 구현하여 이 구성 요소가 삭제될 때 구성 요소 자체를 참조하는 .NET 개체 참조도 삭제되도록 합니다. 특히 이 구성 요소의 Dispose 메서드에서 .NET 개체 참조의 Dispose 메서드를 호출했습니다.
아래와 같이 JSDemoBase.razor 파일에 버튼을 추가합니다.
<button @onclick="@(()=>InvokeDisplayMessageCallerJS("The Button is clicked"))">JS 메서드 호출</button>
<br />
<p >@메시지</p>
버튼 클릭 시 InvokeDisplayMessageCallerJS 메서드를 호출하고 문자열 값을 매개 변수로 전달합니다. 메시지의 업데이트된 값이 화면에 표시됩니다.
계속 읽기
계속 읽으려면 양식을 작성하세요.