【问题标题】:How to call a static JavaScript method from Blazor C# code如何从 Blazor C# 代码调用静态 JavaScript 方法
【发布时间】:2020-03-12 06:32:18
【问题描述】:

首先,我的 JS:

class MyClass {
    static myMethod() {
        alert("TEST");
    }
}

我的 JS 运行时是这样注入的:

[Inject] protected IJSRuntime Js { get; set; }

我想像这样调用静态方法:

Js.InvokeVoidAsync("MyClass.myMethod");

但我得到一个错误:

Microsoft.JSInterop.JSException:在“窗口”中找不到“MyClass”。

是否有一种理智、合理的方法来解决这个问题,或者仅通过将 window.MyClass = MyClass 添加到我的 JS 中?

【问题讨论】:

标签: javascript c# interop blazor


【解决方案1】:

试试这个(假设服务器端 Blazor)。

在您的 _Host.cshtml 文件中:

(function () {
    window.MyClass = {
        myMethod: function () {
            return alert('TEST');
        }
    };
})();

在 .razor 文件中(在顶部):

@*Inject JSRuntime to allow JavaScript Interop *@
@inject IJSRuntime JSRuntime

在 .razor 文件中的方法中:

await JSRuntime.InvokeAsync<string>(
            "MyClass.myMethod", null
            );

见: Blazor JavaScript Interop

【讨论】:

  • 将它包装到 IIFE 有什么好处?你还是把 MyClass 注册到全局作用域,所以封装没用,不是吗?
【解决方案2】:

是的,用窗口对象注册你的方法是正确的。

源码的相关部分可以在这里找到:

https://github.com/aspnet/Extensions/tree/master/src/JSInterop

你会发现:

invokeJSFromDotNet: (identifier: string, argsJson: string) => { ... }

在哪里

@param identifier 标识全局可达函数 调用。

查看findJSFunction,您会看到检查给定标识符是否已注册到窗口对象的部分,如果没有,则会生成您看到的错误:

function findJSFunction(identifier: string): Function {

(...)

    let result: any = window;
    let resultIdentifier = 'window';
    let lastSegmentValue: any;
    identifier.split('.').forEach(segment => {
      if (segment in result) {
        lastSegmentValue = result;
        result = result[segment];
        resultIdentifier += '.' + segment;
      } else {
        throw new Error(`Could not find '${segment}' in '${resultIdentifier}'.`);
      }
    });

【讨论】:

  • 嗯,类可以通过 eval 访问,如果使用正确,这不是邪恶的。我制作了自己版本的“调用静态”和“创建实例”代码,我想知道是否有办法扩展 JSInterop 以使用这些方法。我的意思是我做了一个扩展类,但它使用了额外的 JS 来工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-17
  • 1970-01-01
  • 2018-01-06
  • 2018-03-15
  • 1970-01-01
相关资源
最近更新 更多