Blazor Server键盘控制:解决dotNetReference持久化与事件重复问题
Blazor Server键盘控制解决方案
问题根源
- 匿名函数重复触发:
OnAfterRenderAsync会在每次组件渲染时执行,若未加firstRender判断,会重复绑定keyup事件,导致每次按键触发多次回调。 - 命名函数丢失引用:在自定义命名函数内重新声明
var dotNetReference = dotNetReference,因变量提升规则,局部变量会覆盖外部引用且初始值为undefined,无法正常调用C#方法。
正确实现步骤
1. C#组件代码(修复重复绑定+内存管理)
public class YourComponent : ComponentBase, IDisposable { [Inject] protected IJSRuntime JSRuntime { get; set; } = default!; private DotNetObjectReference<YourComponent>? _dotNetReference; protected async override Task OnAfterRenderAsync(bool firstRender) { // 仅在第一次渲染时绑定事件,避免重复绑定 if (firstRender) { _dotNetReference = DotNetObjectReference.Create(this); await JSRuntime.InvokeVoidAsync("JsFunctions.addKeyboardListener", _dotNetReference); } } [JSInvokable] public void Next() { ClearMessages(); } [JSInvokable] public void Prev() { // 实现Prev逻辑 } [JSInvokable] public void NavigateToOverviewPage() { // 实现导航逻辑 } // 组件销毁时释放引用并解绑事件,避免内存泄漏 public void Dispose() { _dotNetReference?.Dispose(); _ = JSRuntime.InvokeVoidAsync("JsFunctions.removeKeyboardListener"); } private void ClearMessages() { // 你的业务逻辑 } }
2. JavaScript代码(持久化引用+支持解绑)
window.JsFunctions = { addKeyboardListener: function (dotNetReference) { // 闭包捕获外部的dotNetReference,无需重新声明 function handleKeyUp(event) { // 注意:event.key是字符值(如"7"),event.keyCode是数字键码(如数字键7对应55),根据实际需求调整 if (event.key === "7") { dotNetReference.invokeMethodAsync('Prev'); } if (event.key === "8") { dotNetReference.invokeMethodAsync('Next'); } if (event.key === "3") { dotNetReference.invokeMethodAsync('NavigateToOverviewPage'); } } document.addEventListener('keyup', handleKeyUp); // 存储监听函数,用于后续解绑 window._keyboardHandler = handleKeyUp; }, removeKeyboardListener: function () { if (window._keyboardHandler) { document.removeEventListener('keyup', window._keyboardHandler); window._keyboardHandler = null; } } };
关键说明
- 闭包捕获引用:命名函数
handleKeyUp直接使用外部函数传入的dotNetReference,确保引用持久化可用。 - 避免重复绑定:通过
firstRender判断,仅在组件首次渲染时执行事件绑定逻辑。 - 内存泄漏防护:实现
IDisposable接口,在组件销毁时释放DotNetObjectReference并解绑事件,避免内存泄漏。
内容的提问来源于stack exchange,提问作者boxofgiraffes
相关产品推荐
相关产品推荐

