简体   繁体   English

使用 Blazor 调用 JavaScript function(来自外部库)

[英]Call JavaScript function (from external library) with Blazor

I try to call a JS function.我尝试调用 JS function。 The JS script is provided by a third party. JS 脚本由第三方提供。

In simple HTML/JS, I can write:在简单的 HTML/JS 中,我可以编写:

<html>
    <head>
        <script src="myscriptA.js"></script>
        <script src="myscriptB.js"></script>
    </head>
    <body>
        <div id="foo"></div>
        <div id="bar"></div>
        <script>
            var viewer = new foo.Viewer('foo', /*other params*/);
            viewer.function1().then(() => { /*ommited code*/ }).catch((error) => { console.log(error)});
            document.getElementById('bar').addEventListener('click', event => {
                var b1 = new B('bar', /*params*/)});
                var b2 = new B('foo');
            viewer.addB(b1, b2, { click: function(e) { viewer.function2() } });
        </script>
    </body>
</html>

I want to do the same thing with Blazor.我想对 Blazor 做同样的事情。 For the moment, I can reach the myscriptA.js file with my component:目前,我可以使用我的组件访问myscriptA.js文件:

Page3.razor

@page "/Page3"
@inject IJSRuntime JS
@code {
    var scriptA = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./js/myscriptA.js");
    var foo = await JSRuntime.InvokeAsync<IJSObjectReference>("new foo.Viewer", scriptA);
    // I have try:
    var foo = await JSRuntime.InvokeAsync<IJSObjectReference>("new foo.Viewer", "foo", @*other params*@);
    var foo = await JSRuntime.InvokeAsync<IJSObjectReference>("foo.Viewer", "foo", @*other params*@);
    var foo = await JSRuntime.InvokeAsync<IJSObjectReference>("Viewer", "foo", @*other params*@);
    var foo = await JSRuntime.InvokeAsync<IJSObjectReference>("new Viewer", "foo", @*other params*@);
}

For each C# foo variable in my component, my browser's console shows:对于我的组件中的每个 C# foo 变量,我的浏览器控制台显示:

blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Could not find 'new foo.Viewer' ('new foo' was undefined).
      Error: Could not find 'new foo.Viewer' ('new foo' was undefined).
          at https://localhost:5001/_framework/blazor.webassembly.js:1:1287
          at Array.forEach (<anonymous>)
          at e.findFunction (https://localhost:5001/_framework/blazor.webassembly.js:1:1247)
          at b (https://localhost:5001/_framework/blazor.webassembly.js:1:2989)
          at https://localhost:5001/_framework/blazor.webassembly.js:1:3935
          at new Promise (<anonymous>)
          at Object.beginInvokeJSFromDotNet (https://localhost:5001/_framework/blazor.webassembly.js:1:3908)
          at Object.w [as invokeJSFromDotNet] (https://localhost:5001/_framework/blazor.webassembly.js:1:64232)
          at _mono_wasm_invoke_js_blazor (https://localhost:5001/_framework/dotnet.5.0.4.js:1:190800)
          at do_icall (<anonymous>:wasm-function[10596]:0x194e4e)

Updates更新

May 8th, 2021: index.html 2021 年 5 月 8 日:索引.html

As written in the comment ( Call JavaScript function (from external library) with Blazor ), I want to inject myscriptA.js and myscriptB.js only in Page3.razor file and not in another files ( Page1 , Page2 , Page4 , ...). As written in the comment ( Call JavaScript function (from external library) with Blazor ), I want to inject myscriptA.js and myscriptB.js only in Page3.razor file and not in another files ( Page1 , Page2 , Page4 , ... )。

May 11th, 2021: js file 2021 年 5 月 11 日:js 文件

As *.css files for Blazor components, I tried to add a *.js file with the same name as my page:作为 Blazor 组件的 *.css 文件,我尝试添加与我的页面同名的 *.js 文件:

  • Project.csproj
    • Pages folder Pages文件夹
      • Page1.razor
      • Page2.razor
      • Page2.razor.css <-- seen in a Shared\NavMenu.razor Page2.razor.css <-- 见于Shared\NavMenu.razor
      • Page3.razor
      • Page3.razor.js

I've the same error我有同样的错误

You were close.. To load a JS file only where required (e,g,, a specific page), you need to implement the IJSObjectReference interface and utilize the JavaScript module isolation properly.你已经接近了.. 要仅在需要的地方(例如,特定页面)加载 JS 文件,您需要实现IJSObjectReference接口并正确利用 JavaScript 模块隔离。

Razor page: Razor 页面:

@inject IJSRuntime JsRuntime

<h1>My Page</h1>

@code{
private IJSObjectReference MyJsModule { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        try
        {
            // Load the JS Helpers Module
            MyJsModule = await JsRuntime.InvokeAsync<IJSObjectReference>("import", "./js/MyScript.js");
        }
        catch (Exception ex)
        {
            Logger.LogError($"Failed to load JS module. Error: {ex}");
        }
    }
}

private async void AddViewer()
{
    try
    {
        await MyJsModule.InvokeVoidAsync("AddViewer", "foo");
    }
    catch (Exception ex)
    {
        Logger.LogError($"Failed to execute JS function. Error: {ex}");
    }
}

MyScript.js file: MyScript.js 文件:

import "./myScriptWithUsefulCodes.min.js";

export function AddViewer(id) {
    var viewer = new foo.Viewer(id, /*other params*/);
    /* ...Your code... */
}

Read more here: https://docs.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/call-javascript-from-dotnet?view=aspnetcore-5.0#javascript-isolation-in-javascript-modules在此处阅读更多信息: https://docs.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/call-javascript-from-dotnet?view=aspnetcore-5.0#javascript-isolation-in-javascript-模块

Couldn't you just load the JavaScript file in your Blazor Page, the same way as the default Blazor example loads the .json file?难道你不能在你的 Blazor 页面中加载 JavaScript 文件,就像默认的 Blazor 示例加载.json文件一样吗?

And then 'execute' the contents from that string as JavaScript using the IJSRuntime?然后使用 IJSRuntime 将该字符串中的内容“执行”为 JavaScript?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM