Blazor-JavaScript Interop-尚未设置.NET调用调度器 [英] Blazor - JavaScript Interop - No .NET call dispatcher has been set

查看:36
本文介绍了Blazor-JavaScript Interop-尚未设置.NET调用调度器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在试验Blazor WebAssembly app。当我的页面(即index.html)加载时,我希望在加载时向Blazor应用程序传递一个JavaScript数组。尝试call a method from JavaScript时,遇到错误:

Uncaught (in promise) Error: No .NET call dispatcher has been set

我的代码如下:

index.html

<body>
    <app>Loading...</app>

    <div id="blazor-error-ui">
        An unhandled error has occurred.
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a>
    </div>
    <script src="_framework/blazor.webassembly.js"></script>

    <script>
        let items = [
            { name:'Item 1', description:'This is a description of the first item' },
            { name:'Item 2', description:'This is a description of the second item' },
            { name:'Item 3', description:'This is a description of the third item' },
        ];

        try
        {
            DotNet
                .invokeMethodAsync('MyOrg.MyApp.Index', 'LoadItems')
                .then(results => {
                    console.log(results);
                })
            ;
        }
        catch (ex)
        {
            console.log(ex);
        }
    </script>
</body>

Index.razor

@page "/"

@using System.Threading.Tasks;    
@using Microsoft.Extensions.Logging;

@inject ILogger<Index> logger;

<p>
    Items loaded: <span>@items.Count</span>
</p>

@code {
    List<object> items = new List<object>();

    [JSInvokable]
    private Task LoadSnippets() 
    {
        try 
        {
            logger.LogInformation("Loading items...");
            items = new List<object>();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, $"Failed to load items.");
        }
        return Task.CompletedTask;
    }
}

我注意到的第一个区别是文档中显示的示例依赖于static方法。这是一项要求吗?如果是这样的话,这将意味着没有一种方法可以执行日志记录。撇开登录不谈,即使我将static添加到LoadItems方法中,我仍然得到上面列出的错误。我不明白为什么。

简而言之,我正在尝试创建一款无头应用程序。我想使用C#的丰富性来处理数据,我需要将结果传递给依赖于HTML/CSS的UI。谢谢!

推荐答案

欢迎使用Blazor!

首先,我建议阅读Call .Net from js

中的文档

在index.html中包含脚本的方式意味着,脚本是在加载wasm应用程序之前执行的。

要解决这个问题,最好在OnAfterRenderAsync生命周期方法(Lifecycle docs)中使用js interop

因此,如果您将脚本更新为以下内容:

<script>
        netFromJs = {
            staticCall:  function () {
                let items = [
                    { name: 'Item 1', description: 'This is a description of the first item' },
                    { name: 'Item 2', description: 'This is a description of the second item' },
                    { name: 'Item 3', description: 'This is a description of the third item' },
                ];

                try {
                    DotNet
                        .invokeMethodAsync('wasmprerender.Client', 'LoadItems')
                        .then(results => {
                        console.log(results);
                    });
                }
                catch (ex) {
                    console.log(ex);
                }
            }
        }
    </script>

然后在您的组件(页面也是组件)中,您将能够执行以下操作:

@inject IJSRuntime _js

@code {
    static List<object> items = new List<object>();

    [JSInvokable]
    public static Task LoadItems()
    {
        try
        {
            Console.WriteLine("Loading items");
            items = new List<object>();
        }
        catch (Exception ex)
        {
        }

        return Task.CompletedTask;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await _js.InvokeVoidAsync("netFromJs.static");
    }
}

来解决您关于静态呼叫的注意事项。您的示例使用静态方法调用,Blazor还支持实例方法调用。您将在此处找到一个很好的示例Instance call

最后,我不太推荐Touch index.html。创建并引用单独的.js文件,或从.NET 5 RC1中使用Js isolation

这篇关于Blazor-JavaScript Interop-尚未设置.NET调用调度器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆