1

我有一个基于 .NET Core 3.1 构建的 Blazor 应用程序,我需要能够访问 USB 端口资源。我不断收到错误:

此时无法发出 JavaScript 互操作调用。这是因为组件是静态渲染的。启用预呈现后,JavaScript 互操作调用只能在 OnAfterRenderAsync 生命周期方法期间执行。

我有一个非常简单的 Blazor 组件,其中包含 Blazor.Extensions.WebUSB 库

public partial class Recordings : ComponentBase
{
    [Inject] private IUSB _usb { get; set; }
    [Inject] private ILogger<Recordings> _logger { get; set; }
    [Inject] private IJSRuntime _runtime { get; set; }

    private bool _initialized = false;


    protected override Task OnAfterRenderAsync(bool firstRender)
    {
        if (!_initialized)
        {
            this._usb.OnConnect += OnConnect;
            this._usb.OnDisconnect += OnDisconnect;
            this._usb.Initialize();
            this._initialized = true;
        }
        return Task.CompletedTask;

    }

    protected async Task GetDevices()
    {
        var devices = await this._usb.GetDevices();

        if (devices != null && devices.Length > 0)
        {
            _logger.LogInformation("Device list received");
        }
    }

    private void OnConnect(USBDevice device)
    {
        this._logger.LogInformation("Device connected");
    }

    private void OnDisconnect(USBDevice device)
    {
        this._logger.LogInformation("Device disconnected");
    }
}

即使我按照建议在 OnAfterRenderAsync 中执行 JS 互操作,我仍然会遇到相同的错误。我尝试延迟对 _usb.Initialize 的调用,直到按下按钮(这意味着组件肯定应该已经完成​​渲染。

我尝试通过将 _Host.cshtml 中的渲染模式属性设置为 Server 而不是 ServerPrerendered 来禁用预渲染,但没有任何改变。

4

1 回答 1

2

你的代码应该是这样的:

 protected override Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        this._usb.OnConnect += OnConnect;
        this._usb.OnDisconnect += OnDisconnect;
        this._usb.Initialize();
        this._initialized = true;
    }
    return Task.CompletedTask;

}

注意:当 firstRender 变量为 true(仅出现一次)时,您可以使用 JSInterop。在此之前你不能。这是初始化 JavaScript 对象的正确时间和地点。

OnAfterRender(Boolean) 和 OnAfterRenderAsync(Boolean) 生命周期方法对于执行互操作或与从 @ref 接收的值进行交互很有用。使用 firstRender 参数确保初始化工作只执行一次。

希望这可以帮助...

于 2020-02-13T13:39:50.400 回答