Estoy tratando de incrustar un reproductor de audio usando una biblioteca de javascript llamada Wavesurfer.js en mi componente Blazor. Estoy configurando los ID de los divs necesarios generando GUID para ellos en la página razor.cs y luego entregando esos valores al componente .razor :
// WavePlayer.razor.cs private Guid _mainDivGuid; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { _interop = new WavesurferJsInterop(_js, DotNetObjectReference.Create<WavePlayer>(this)); if (_interop != null) { await _interop.Create(_mainDivGuid, Options); //preload file if URL already supplied if (Url != null) { await Load(Url); } } } } protected override void OnInitialized() { _mainDivGuid = Guid.NewGuid(); } // WavePlayer.razor <div class="wavesurfer-ui-main" id="@_mainDivGuid"></div> En la interoperabilidad js, llama al wavesurfer.js real donde se invoca el método Create y pasa el GUID del div donde se debe representar el reproductor.
Cuando ejecuto el componente, aparece un error Error: Container element not found y puedo confirmar esto en js agregando una prueba para
if (!document.getElementById(mainDivGuid)) { console.log(mainDivGuid); console.log("No div element found for wavesurfer mainDivGuid"); // this gets logged } mainDivGuid se está creando, es el GUID correcto, pero cuando se invoca el método Create , aparentemente el div no existe en el DOM.
¿No debería usar el método OnAfterRenderAsync para garantizar que el DOM se represente por completo antes de que se llame a Create ? ¡No estoy seguro de cómo el reproductor de olas puede intentar activar sus propios eventos antes de que exista el contenedor!
Debe utilizar una ElementReference cuando trabaje entre código JS y .NET. Algo como a continuación:
// WavePlayer.razor @inject IJSRuntime Js <div class="wavesurfer-ui-main" ref="@_mainDiv"></div> @code { public ElementReference _mainDiv; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { await Js.InvokeVoidAsync("Create", _mainDiv); } } }En JS, el argumento de su función será el objeto DOM.
function Create(thisIsTheDomObjectHere) { thisIsTheDomObjectHere.innerHTML("Hi there"); }Ver más aquí: