Blazor 서버에서 브라우저로 사용자 인터페이스를 변경하면 이벤트가 발생합니다.
클라이언트 이벤트(예를 들어 단추 클릭)가 Blazor 서버로 전송되고 서버가 상태를 변경하고 다시 표시됩니다.그러나 일부 응용 프로그램에서도 다른 곳에서 사건을 일으킬 수 있다.본고에서 이러한 유형의 사건을'서버가 일으킨 사건'이라고 부른다.서버에서 발생하는 이벤트는 트리거될 수 있습니다
이러한 이벤트로 인해 상태가 변경되면 Blazor 서버는 자동으로 구성 요소를 다시 렌더링하지 않습니다.구성 요소 업데이트는 두 가지 문제를 해결해야 합니다.
StateHasChanged()
으로 전화를 걸어 이 문제를 해결할 수 있습니다.StateHasChanged()
을 호출하면 무시되거나 렌더링 라인 밖으로 끝날 때 이상이 발생할 수 있습니다.반대로 InvokeAsync
에 작업을 전달할 수 있습니다. 이 작업은 오른쪽 라인과 렌더링기의 동기화 상하문에서 호출됩니다.StateHasChanged()
에 전송된 작업에서 InvokeAsync
을 호출하면 Blazor 서버는 구성 요소를 성공적으로 다시 보여주고 신호기를 사용하여 변경 사항을 브라우저로 전송합니다.서버에서 발생하는 이벤트를 시뮬레이션하기 위해
Timer
을 사용할 수 있습니다. 이것은 일정 시간마다 코드를 호출합니다.서버에서 발생한 이벤트 예
이 GitHub Repository에서 예시 코드를 찾을 수 있습니다.
선행 조건:
mkdir BlazorServerSample
cd BlazorServerSample
dotnet new blazorserver
Pages\Counter.razor
을 업데이트합니다.@page "/counter"
@implements IDisposable
@using System.Timers
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
Console.WriteLine($"Count incremented: {currentCount}");
}
private Timer timer;
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
timer = new Timer();
timer.Interval = 1000;
timer.Elapsed += OnTimerInterval;
timer.AutoReset = true;
// Start the timer
timer.Enabled = true;
}
base.OnAfterRender(firstRender);
}
private void OnTimerInterval(object sender, ElapsedEventArgs e)
{
IncrementCount();
}
public void Dispose()
{
// During prerender, this component is rendered without calling OnAfterRender and then immediately disposed
// this mean timer will be null so we have to check for null or use the Null-conditional operator ?
timer?.Dispose();
}
}
카운터razor는 현재 1000ms (1s) 간격의 타이머를 설정합니다.카운터 페이지를 보고 있으면 초당 IncrementCount()
으로 호출합니다.다른 페이지로 이동하면
Dispose
을 호출하고 정지 간격 때 타이머 자원을 제거합니다.dotnet run
https://localhost:5001
에 있습니다.currentCount
상태 변경이 브라우저에 반영되지 않았습니다.이것은 출력의 모양입니다.dotnet run
# output:
# info: Microsoft.Hosting.Lifetime[0]
# Now listening on: https://localhost:5001
# info: Microsoft.Hosting.Lifetime[0]
# Now listening on: http://localhost:5000
# info: Microsoft.Hosting.Lifetime[0]
# Application started. Press Ctrl+C to shut down.
# info: Microsoft.Hosting.Lifetime[0]
# Hosting environment: Development
# info: Microsoft.Hosting.Lifetime[0]
# Content root path: C:\Users\niels\source\repos\BlazorServerEvents
# Count incremented: 1
# Count incremented: 2
# Count incremented: 3
# Count incremented: 4
# Count incremented: 5
# Count incremented: 6
# Count incremented: 7
# Count incremented: 8
클릭미(Click me) 단추를 누르면 브라우저에 표시된 숫자가 서버의 currentCount
에 갑자기 반영됩니다.클라이언트 이벤트가 Blazor 서버로 전송될 때, 자신이 어느 라인에 있는지 걱정할 필요도, Blazor 상태 변경을 현저하게 알릴 필요도 없습니다.이 모든 것은 자동으로 발생한 것이다.
"나를 클릭"단추를 누르면
IncrementCount
이 호출되고 currentCount
이 추가됩니다. 이 필드는 타이머가 증가함에 따라 증가합니다.그러면 Blazor가 최신 currentCount
상태로 어셈블리를 다시 렌더링합니다.클라이언트와 서버에서 상태가 동기화되는지 확인하기 위해
InvokeAsync(() => StateHasChanged());
을 타이머 간격 리셋에 추가합니다.업데이트 함수 OnTimerInterval
은 다음과 같습니다.private void OnTimerInterval(object sender, ElapsedEventArgs e)
{
IncrementCount();
InvokeAsync(() => StateHasChanged());
}
응용 프로그램을 다시 실행하면 브라우저의 숫자가 초당 증가합니다!Blazor 구성 요소 외부에서 발생한 이벤트
타이머는 Blazor 구성 요소 클래스에서 발생하는 서버에서 발생하는 이벤트를 처리하는 방법을 보여 주지만, 다른 이벤트는 구성 요소 외부에서 발생할 수 있습니다.이 경우 이벤트 데이터를 활성 구성 요소로 보내는 방법은 무엇입니까?이 문제를 해결하는 데는 여러 가지 방법이 있는데, 여기에는 두 가지 건의가 있다.
총결산
WebSocket은 양방향 영구 연결로 여러 메시지를 보낼 수 있습니다.WebSocket은 서버가 언제든지 클라이언트에게 메시지를 전달할 수 있도록 합니다.Blazor 서버는 Signal에, Signal은 웹소켓에 구축됩니다.Blazor 서버는 지속적인 양방향 연결로 인해 브라우저에서 요청하지 않고도 UI 변경 사항을 브라우저로 전송할 수 있습니다.반대로 사용자 인터페이스의 변경은 서버가 일으킨 이벤트에 의해 촉발될 수 있다.상태 및 UI 변경이 클라이언트로 전송되도록 하려면
InvokeAsync(() => StateHasChanged());
을 호출해야 합니다.이 반례는 반기후일 수도 있지만, 타이머가 아닌 실시간 데이터베이스를 사용하는 것을 상상해 보세요.Blazor 서버 UI를 실시간으로 다시 렌더링할 수 있습니다!
Reference
이 문제에 관하여(Blazor 서버에서 브라우저로 사용자 인터페이스를 변경하면 이벤트가 발생합니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/swimburger/pushing-ui-changes-from-blazor-server-to-browser-on-server-raised-events-21f1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)