Вызов javascript из Blazor приводит к ошибке - PullRequest
1 голос
/ 13 февраля 2020

У меня есть приложение Blazor. NET Core 3.1, и мне нужно иметь доступ к ресурсам USB-порта. Я продолжаю получать сообщение об ошибке:

JavaScript вызовы взаимодействия не могут быть выполнены в это время. Это потому, что компонент статически визуализируется. Когда предварительный рендеринг включен, JavaScript вызовы взаимодействия могут выполняться только во время метода жизненного цикла OnAfterRenderAsyn c.

У меня есть довольно простой компонент 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");
    }
}

И хотя я выполняю JS взаимодействие в OnAfterRenderAsyn c, как и предполагалось, я все еще получаю ту же ошибку. Я пытался отложить вызов _usb.Initialize до тех пор, пока не будет нажата кнопка (то есть компонент определенно должен был закончить рендеринг.

Я попытался отключить предварительный рендеринг, установив атрибут режима рендеринга в _Host.cs html на сервер вместо ServerPrerendered, но ничего не изменилось.

1 Ответ

2 голосов
/ 13 февраля 2020

Ваш код должен выглядеть следующим образом:

 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) и OnAfterRenderAsyn c (Boolean) полезны для выполнения взаимодействия или взаимодействия со значениями, полученными из @ref. Используйте параметр firstRender, чтобы гарантировать, что работа по инициализации выполняется только один раз.

Надеюсь, это поможет ...

...