I don't know of a way other then JS interop. So what you can do ( based my work on the docs here and here:
Add a JS Invokable update method in your razor component (i'm using Index.razor
). Note, this is a bit weird, as the JSInvokable
method needs to be static.
private static Func<Task> updateAsyncAction;
protected override void OnInitialized()
{
base.OnInitialized();
updateAsyncAction = async () => { await InvokeAsync(StateHasChanged); }; // triggers a rerender.
}
[JSInvokable]
public static async Task Update()
{
await updateAsyncAction.Invoke();
}
Add a caller in a e.g. wwwroot\Interop.js
file:
window.IndexFunctions = {
EnableOnFocusUpdate: function () {
window.addEventListener("focus", function () {
DotNet.invokeMethodAsync('{APP ASSEMBLY}', 'Update'); // The placeholder {APP ASSEMBLY} is the app's app assembly name.
});
}
}
In index.html
, add the script before the closing body tag using
<script src="Interop.js"></script>
Finally, you have to enable the js event listener in the razor page
@inject IJSRuntime JS
...
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (firstRender)
{
await JS.InvokeVoidAsync("IndexFunctions.EnableOnFocusUpdate");
}
}
However, you need to click the blazor window once for this to start working... so maybe some more magic is needed.
edit: As noted in the comments, Update
will remain registered even if you navigate away from the page, thus rerendering on focus. I'm not seeing an exception though, so in WASM it seems the object/instance is not destroyed.
It would be nice if a razor component would have some sort of OnNavigateAway
or destructor, which we could use to remove the instance from updateAsyncAction
. The best thing we can now do is do another JSInterop call using removeEventListener
.
I will maybe ask this on the Blazor github.