从 blazor 服务器 c# 调用 javascript 文档事件侦听器,而不重复事件,但保留 dotnetreference

Calling javascript document event listener from blazor server c# without event repeating but maintaining dotnetreference

提问人:boxofgiraffes 提问时间:11/11/2023 最后编辑:boxofgiraffes 更新时间:11/14/2023 访问量:32

问:

Blazor 服务器 - 我想使用键盘键来控制屏幕。

1.我将dotNetReference传递给我的javascript函数。

    protected async override Task OnAfterRenderAsync(bool firstRender)
    {
        
        var dotNetReference = DotNetObjectReference.Create(this);
        await JSRuntime.InvokeVoidAsync("JsFunctions.addKeyboardListenerEvent", dotNetReference);

    }
  1. 我运行 javascript 并返回对 razor 页面的调用。

当它是匿名函数时,无论发生多少次键控,它都会重复调用。定义带有 eventListener 的函数调用时,我丢失了 dotNetReference,但它正确运行了一次!

  1. 我非常接近,但无法弄清楚如何保留dotNetReference,以便它可以调用C#方法

匿名

    addKeyboardListener: function (dotNetReference) {
        

        document.addEventListener('keyup', function(event) {
            /*document.removeEventListener('keyup');*/
            if (event.key == 7) {
                dotNetReference.invokeMethodAsync('Prev');
            }
            if (event.key == 8) {
                dotNetReference.invokeMethodAsync('Next');
            }
            if (event.key == 3) {
                dotNetReference.invokeMethodAsync('NavigateToOverviewPage');
            }
        });

定义 addKeyboardListener: 函数 (dotNetReference) {

    document.addEventListener('keyup', myFunction) 


    function myFunction(event) {

        // Calls a method by name with the [JSInokable] attribute (above)
        var dotNetReference = dotNetReference
        if (event.key == 7) {
            dotNetReference.invokeMethodAsync('Prev');
        }
        if (event.key == 8) {
            dotNetReference.invokeMethodAsync('Next');
        }
        if (event.key == 3) {
            dotNetReference.invokeMethodAsync('NavigateToOverviewPage');
        }
    }

}
C#
[JSInvokable]
public  void Next()
{
    ClearMessages();
}

一定有一种方法可以持久化 dotNetReference,但我无法弄清楚,并且必须缺少一种明显的方法来解决这个问题。谢谢。

javascript .net blazor-server-side

评论


答:

1赞 boxofgiraffes 11/11/2023 #1

好吧,多亏了这个链接,我才能工作: 参数

  1. 保留这个:
    protected async override Task OnAfterRenderAsync(bool firstRender)
    {
        
        var dotNetReference = DotNetObjectReference.Create(this);
        await JSRuntime.InvokeVoidAsync("JsFunctions.addKeyboardListenerEvent", dotNetReference);
    
    }
  1. 将 dotNetReference 存储为您添加 EventListener 的对象的属性(在我的例子文档中):
    def: function test(dotNetReference) {
        document.dotNetRef = dotNetReference;
        document.addEventListener('keyup', abc)
    }
  1. abc 现在可以访问 dotNetReference:
    abc: function myFunction1(e) {
        dn = e.currentTarget.dotNetRef;
        // Calls a method by name with the [JSInokable] attribute (above)
    
        if (e.key == 7) {
            dn.invokeMethodAsync('Prev');
        }
        if (e.key == 8) {
            dn.invokeMethodAsync('Next');
        }
        if (e.key == 3) {
            dn.invokeMethodAsync('NavigateToOverviewPage');
        }
    
    }

评论

1赞 Kurt Hamilton 11/11/2023
这不会为每个渲染添加一个事件侦听器吗?因此,如果视图更改状态 3 次,导致 3 次呈现 + 初始呈现,则每个键盘事件将调用 C# 函数 4 次。我可能误解了您想要表达的内容,但您可能只想在第一次渲染时添加事件侦听器?
0赞 boxofgiraffes 11/12/2023
在我所讨论的第二个代码块(第一个 JavaScript 块)中,这正是正在发生的事情。但是,在我的回答中,我定义了该函数并将其从 addListener 调用中删除。由于 addListener 仅被调用 OnAfterFirstRender,因此它只注册了一次。我从那里开始的问题是将 dotnetreference 传递给现在定义的函数。一旦我将其作为文档的属性附加到我的答案中,它就可用了,因此使用定义的函数注册一次侦听器,然后在每次键入时调用该侦听器一次!