I’ve created a sample of the simplest asynchronous processing that can be achieved with Blazor Server, and I’d like you to refer to it. The source code is now available on GitHub.
* The essence of high productivity of Blazor Server is that you can easily implement this creation without writing JavaScript.
Source Code Structure
I just added LoadingOverlay.razor LoadingOverlay.razor.css to the Blazor Server template in the Visual Studio project and modified Counter.razor a bit.
Explanation of source code changes
LoadingOverlay.razor
・Parts of the “Processing…” screen.
・Visible parameter variable to show/hide the “Processing…” screen with if (Visible).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@if (Visible) { <div id="loading"> <div class="w-100 d-flex justify-content-center align-items-center"> <div class="spinner-border text-primary spinner-custom" role="status"></div> </div> <strong><span>処理中です...</span></strong><br> </div> } @code { [Parameter] public bool Visible { get; set; } = false; } |
LoadingOverlay.razor.css
・CSS dedicated to the “Processing…” screen part.
・z-index: 999991″ displays the “Processing…” screen part at the front.
・By displaying the “Processing…” screen part, which covers the entire screen, at the top of the screen, you can prevent the user from hitting the button repeatedly while the process is running, or from starting another process before the process is finished.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
.spinner-border.spinner-custom { width: 8rem; height: 8rem; border: 0.5em solid currentColor; border-right-color: transparent; } #loading { position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; background-color: black; z-index: 999991; -moz-opacity: 0.5; opacity: .50; filter: alpha(opacity = 50); text-align: center; color: #007bff; padding-top: 350px; } #loading span { font-size: 1.85em; color: #FFF; } |
Counter.razor
・Sample screen using the “Processing…” screen part.
・JsRuntime.InvokeAsync() is used to implement the confirmation message/completion message as a general movement with JavaScript confirm/alert.
・The “Processing…” screen part is embedded with , and the IsLoadingOverlay variable is used to show/hide the “Processing…” screen.
・Changes in the IsLoadingOverlay variable are reflected to the browser by executing StateHasChanged().
・When the button is clicked, all the processing in the IncrementCount() event handler is implemented synchronously, but by displaying the “Processing…” screen in the front until the processing is completed, the movement seen by the user is asynchronous.
・(Important) The ability to implement all processing in an event handler asynchronously without turning it into a service means that the source code implementation becomes very simple.
The ability to implement synchronously means that all business logic can be implemented in static classes to improve performance. Data is passed to each static method in the instance class.
・The names of variables and methods in Blazor Server can be localized, such as the ビジネスロジック() method. I always think that Japanese people can make many things go more smoothly if they write their programs using a lot of Japanese.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
@page "/counter" <h1>Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> <LoadingOverlay Visible="@IsLoadingOverlay" /> @code { [Inject] private IJSRuntime JsRuntime { get; set; } private bool IsLoadingOverlay = false; private int currentCount = 0; private async Task IncrementCount() { var confirmed = await JsRuntime.InvokeAsync<bool>("confirm", "開始しますか?"); if (!confirmed) { return; } IsLoadingOverlay = true; StateHasChanged(); await ビジネスロジック(); currentCount++; IsLoadingOverlay = false; StateHasChanged(); await JsRuntime.InvokeVoidAsync("alert", "完了しました。"); } /// <summary> /// ビジネスロジック、DB処理などは全てstaticで実装するとパフォーマンスが良い。 /// </summary> private static async Task ビジネスロジック() { // なんらかの重たい処理を実行 Start await Task.Delay(5000); // なんらかの重たい処理を実行 End } } |
StateHasChanged() 補足
In the early days of .Net Core 5.0, there was a case that variable changes were not reflected in the browser when StateHasChanged() was executed. This was resolved by adding an await Task.Delay(1) to create a timing for the thread to switch.
Blazor Server の画面で処理中オーバーレイを表示する
How does Blazor Server work?
_Host.cshtml
・_framework/blazor.server.js is embedded in _Host.cshtml, and blazor.server.js is the main body of the front side of Blazor Server.
・blazor.server.js retrieves the DOM from the web server at a frequency of milliseconds, and if there is any change in the DOM, it is reflected in the HTML on the browser side, and the screen displayed on the browser changes in real time.
・The DOM on the web server side will change when StateHasChanged() is executed.
・The DOM on the web server side will be changed by executing StateHasChanged(). ・ StateHasChanged() will be executed automatically after the event handler execution is finished, so it will look like the event handler execution result is reflected in the browser.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
@page "/" @namespace WebApplication1.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @{ Layout = null; } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>WebApplication1</title> <base href="~/" /> <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" /> <link href="css/site.css" rel="stylesheet" /> <link href="WebApplication1.styles.css" rel="stylesheet" /> </head> <body> <component type="typeof(App)" render-mode="ServerPrerendered" /> <div id="blazor-error-ui"> <environment include="Staging,Production"> An error has occurred. This application may no longer respond until reloaded. </environment> <environment include="Development"> An unhandled exception has occurred. See browser dev tools for details. </environment> <a href="" class="reload">Reload</a> <a class="dismiss">🗙</a> </div> <script src="_framework/blazor.server.js"></script> </body> </html> |
Visual Studio Project
The Visual Studio project template we used is Blazor Server 5.0 without authentication and without HTTPS.
コメント