Estoy tratando de envolver una biblioteca de JavaScript externa (una de arrastrar y soltar) que realiza modificaciones de DOM, pero realmente no entiendo cómo interactúa blazor de esta manera.
Un ejemplo sencillo:
JavaScript:
function ModifyDOM(dotNetHelper, element) { element.innerText = "hello"; dotNetHelper.invokeMethodAsync("Update"); }Blazor:
@inject IJSRuntime JS <div @ref="list"> @foreach (var color in colors) { <div @key="color">@color</div> } </div> @code { ElementReference list; List<string> colors = new() { "primary", "secondary", "success", "danger", "warning", "info", "light", "dark" }; private DotNetObjectReference<FetchData>? dotNetHelper; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { dotNetHelper = DotNetObjectReference.Create(this); await JS.InvokeVoidAsync("ModifyDOM", dotNetHelper, list); } } [JSInvokable] public async Task Update() { @* await Task.Yield(); *@ await InvokeAsync(StateHasChanged); // here I'm expecting to reload de original DOM, but it's not happening } public void Dispose() { dotNetHelper?.Dispose(); } }Cuando llamo a StateHasChanged, esperaba que Blazor volviera a dibujar el RenderTree original, pero no sucedió. Mantiene el texto interno "hola".
--- ACTUALIZAR ---
Este es un ejemplo completo, quiero ajustar SortableJS para ordenar listas porque no hay una implementación similar en Blazor
Pero como puede ver en el video a continuación, parece que Blazor se está equivocando al actualizar el componente (en el registro de la consola estoy escribiendo las listas actuales de Blazor)
Debe realizar todas las modificaciones del DOM en su aplicación Blazor. Blazor tiene su propia representación binaria interna del DOM. Cuando representa algo, calcula la diferencia entre la representación DOM actual y la nueva. Cambia el DOM en el navegador, pero su representación en Blazor permanece sin cambios. Es por eso que StateHashChanged() no tiene efecto en su ejemplo.
<div @ref="list"> @foreach (var color in colors) { <div @key="color">@color</div> } </div> En este caso, los colors de la colección no cambian y, por lo tanto, "Blazor piensa" que no hay cambios que aplicar al DOM.
El código de representación de Blazor no tiene idea de que cambió el texto en JavaScript.
...cómo blazor interactúa de esta manera.
Blazor tiene su propia copia del Dom (como un 'dom en la sombra' pero afaik usando su propia implementación).
En una nueva representación, crea una nueva copia (parcial) y la compara con la anterior. Cualquier diferencia se propaga al DOM real.
Entonces, cuando JS realiza un cambio en el DOM real, Blazor no lo ve y esos cambios permanecerán (generalmente una ventaja) hasta que presione F5 o haga que Blazor piense que ha cambiado.
Una mejor práctica sería mantener a Blazor y JS alejados entre sí, pero cuando desee restablecer su lista: