我不知道除了 JS 互操作之外的其他方法。那么你可以做什么(基于我在文档here 和here 上的工作:
在你的 razor 组件中添加一个 JS Invokable 更新方法(我使用的是Index.razor)。注意,这有点奇怪,因为JSInvokable 方法需要是静态的。
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();
}
在 e.g. 中添加调用者wwwroot\Interop.js文件:
window.IndexFunctions = {
EnableOnFocusUpdate: function () {
window.addEventListener("focus", function () {
DotNet.invokeMethodAsync('{APP ASSEMBLY}', 'Update'); // The placeholder {APP ASSEMBLY} is the app's app assembly name.
});
}
}
在index.html 中,在结束正文标记之前添加脚本
<script src="Interop.js"></script>
最后,你必须在剃须刀页面中启用js事件监听器
@inject IJSRuntime JS
...
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (firstRender)
{
await JS.InvokeVoidAsync("IndexFunctions.EnableOnFocusUpdate");
}
}
但是,您需要单击一次 blazor 窗口才能开始工作……所以可能需要更多的魔法。
edit:如 cmets 中所述,Update 将保持注册状态,即使您离开该页面也是如此,因此会重新呈现焦点。不过我没有看到异常,所以在 WASM 中,对象/实例似乎没有被破坏。
如果 razor 组件有某种OnNavigateAway 或析构函数,我们可以使用它从updateAsyncAction 中删除实例,那就太好了。我们现在能做的最好的事情是使用removeEventListener 进行另一个JSInterop 调用。
我可能会在 Blazor github 上问这个问题。