Window Event Listener
JS interop, JSinterop, IJSRuntime, IAsyncDisposable, jsModule, DotNetObjectReference, IJSObjectReference, BlazorComponent.razor.js 資源釋放等。
引言
開發 Blazor 共用元件專用於監聽 Brower Window Events,如:focus 以操作 App。
為工作紀錄。
關鍵程式碼紀錄
Blazor 元件,放在共享目錄 Shared
。
@*
* 監聽 Browser Window 訊息。
* 現在只支援監聽 window.focus 訊息。
* ※注意:建議放置在 page 層級,且只放一個。若同時放置多處只有最後一個有效。
*@
@using Microsoft.JSInterop
@implements IAsyncDisposable
@inject IJSRuntime jsr
@code {
[Parameter] public EventCallback OnFocus { get; set; }
//## Resource
DotNetObjectReference<WindowEventListener>? dotNetObject;
IJSObjectReference? jsModule;
public async ValueTask DisposeAsync()
{
if (jsModule != null)
{
// 反註冊監聽 Browser Window 訊息
await jsModule.InvokeVoidAsync("unregisterWindowEventHandler");
// 釋放資源
await jsModule.DisposeAsync();
}
dotNetObject?.Dispose();
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
dotNetObject = DotNetObjectReference.Create(this);
jsModule = await jsr.InvokeAsync<IJSObjectReference>(
"import", "./Shared/WindowEventListener.razor.js");
// 註冊監聽 Browser Window 訊息
await jsModule.InvokeVoidAsync("registerWindowEventHandler", dotNetObject);
}
}
[JSInvokable]
public Task OnWindowFocus() => OnFocus.InvokeAsync();
}
Blazor 元件關聯的 JavaScript code。 依部署對應規則將會部署到:./Shared/WindowEventListener.razor.js
。
let _dotNetObject = null;
function onFocus(event) {
// events up
console.debug('window.onFocus =>', _dotNetObject);
_dotNetObject && _dotNetObject.invokeMethodAsync("OnWindowFocus");
}
export async function registerWindowEventHandler(dotNetObject) {
_dotNetObject = dotNetObject;
console.debug('註冊監聽訊息…', dotNetObject);
window.addEventListener("focus", onFocus);
}
export async function unregisterWindowEventHandler() {
console.debug('反註冊監聽訊息…', _dotNetObject);
window.removeEventListener("focus", onFocus);
_dotNetObject = null;
}
應用:每當使用者 focus 進此 page 皆重新刷新頁面以重取最新狀態。
@page "/foopage"
@inject NavigationManager navSvc
<MudContainer>
[...page content...]
</MudContainer>
<WindowEventListener OnFocus=HandleWindowFocus />
@code {
...[略]...
Task HandleWindowFocus()
{
//※ 每當使用者 focus 進此 page 皆重新刷新頁面以重取最新狀態。
navSvc.NavigateTo(navSvc.Uri, true); // reload this page.
return Task.CompletedTask;
}
}
參考文件
Last updated