如何从Blazor C#代码调用静态JavaScript方法

时间:2019-11-16 06:49:17

标签: javascript c# interop blazor

首先,我的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中?

2 个答案:

答案 0 :(得分:3)

尝试一下(假设服务器端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

答案 1 :(得分:0)

是的,向window对象注册方法是正确的。

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

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

浏览它会发现:

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

其中

  

@param标识符将全局可访问函数标识为   调用。

看看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}'.`);
      }
    });