Interoperabilidad de JavaScript con Blazor

Completado

Blazor usa componentes de C# en lugar de JavaScript para crear páginas web o secciones HTML con contenido dinámico. Pero puede usar la interoperabilidad de JavaScript de Blazor (interoperabilidad de JS) para llamar a bibliotecas de JavaScript en aplicaciones de Blazor y a funciones de JavaScript desde código de C# de .NET.

En esta unidad, aprenderá a llamar a JavaScript desde código de C# en una página de Blazor y a invocar métodos de C# desde funciones de JavaScript. En la siguiente unidad, se usa un componente de alerta de una biblioteca de JavaScript para actualizar el sitio web de entrega de pizzas de Blazor.

Uso de la interoperabilidad de JavaScript de Blazor

Un componente típico de Blazor usa diseño y lógica de la interfaz de usuario para representar HTML en tiempo de ejecución. Usará código de C# para controlar eventos y otras características de página dinámicas que interactúan con el usuario y con los servicios externos. En muchas ocasiones, no es necesario usar código de JavaScript. En su lugar, puede usar Blazor con las bibliotecas de .NET, que proporcionan muchas funcionalidades equivalentes.

Sin embargo, a veces es necesario usar una biblioteca de JavaScript existente. Por ejemplo, algunas bibliotecas de JavaScript de código abierto representan componentes y controlan elementos de la interfaz de usuario de manera especializada. O bien, podría tener código JavaScript existente que haya probado y comprobado y que quiera reutilizar en lugar de convertirlo en C#.

Puede integrar bibliotecas de JavaScript en las aplicaciones mediante la interoperabilidad de JavaScript con Blazor, o interoperabilidad de JS. La interoperabilidad de JS se usa para llamar a funciones de JavaScript desde métodos de .NET y para invocar métodos de .NET desde funciones de JavaScript. La interoperabilidad de JS controla la serialización de datos y referencias de objetos entre Blazor y JavaScript para facilitar la transición entre ellos.

Carga de código de JavaScript en una aplicación de Blazor

JavaScript se agrega a una aplicación de Blazor de la misma manera que se agrega a una aplicación web HTML estándar mediante el elemento <script> HTML. La etiqueta <script> se agrega después de la etiqueta <script src="_framework/blazor.*.js"></script> existente en el archivo Pages/_Host.cshtml o en el archivo wwwroot/index.html, según el modelo de hospedaje de Blazor. Para más información, consulte Modelos de hospedaje Blazor en ASP.NET Core.

Es mejor no colocar scripts en el elemento <head> de la página. Blazor solo controla el contenido del elemento <body> de una página HTML, por lo que la interoperabilidad de JS podría producir un error si los scripts dependen de Blazor. Además, es posible que la página se muestre más lentamente debido al tiempo que tarda en analizar el código de JavaScript.

La etiqueta <script> funciona como en una aplicación web HTML. Puede escribir código directamente en el cuerpo de la etiqueta o puede hacer referencia a un archivo de JavaScript existente. Para más información, consulte Interoperabilidad de JavaScript en Blazor de ASP.NET Core (interoperabilidad de JS), sección Ubicación de JavaScript.

Importante

Coloque los archivos de JavaScript en la carpeta wwwroot del proyecto de Blazor.

Otra opción es insertar el elemento <script> que haga referencia a un archivo de JavaScript en la página Pages/_Host.cshtml dinámicamente. Este enfoque es útil si tiene que cargar scripts diferentes, en función de las condiciones que solo se puedan determinar en tiempo de ejecución. Además, este enfoque puede acelerar la carga inicial de la aplicación si desencadena la lógica con un evento que se active después de representar una página. Para más información, consulte Inicio de Blazor en ASP.NET Core.

Llamada a JavaScript desde código de .NET

Use IJSRuntime para llamar a una función de JavaScript desde código de .NET. Para que el entorno de ejecución de interoperabilidad de JS esté disponible, inserte una instancia de la abstracción IJSRuntime en una página de Blazor, después de la directiva @page cerca del principio del archivo.

La interfaz IJSRuntime expone los métodos InvokeAsync y InvokeVoidAsync para invocar código de JavaScript. Use InvokeAsync<TValue> para llamar a una función de JavaScript que devuelve un valor. De lo contrario, llame a InvokeVoidAsync. Como los nombres lo sugieren, ambos métodos son asincrónicos, así que use el operador await de C# para capturar los resultados.

El parámetro para el método InvokeAsync o InvokeVoidAsync es el nombre de la función de JavaScript que se va a invocar, seguido de todos los argumentos que requiera la función. La función de JavaScript debe formar parte del ámbito window o de un subámbito de window. Los argumentos deben ser serializables por JSON.

Nota:

La interoperabilidad de JS solo está disponible cuando la aplicación de Blazor Server ha establecido una conexión SignalR con el explorador. No se pueden hacer llamadas de interoperabilidad hasta que se complete la representación. Para detectar si la representación ha finalizado, use el evento OnAfterRender o OnAfterRenderAsync en el código de Blazor.

Uso de un objeto ElementReference para actualizar el DOM

Blazor mantiene una representación de Document Object Model (DOM) como árbol de representación virtual. A medida que cambia la estructura de la página, Blazor genera un nuevo árbol de representación que contiene las diferencias. Una vez completados los cambios, Blazor recorre en iteración las diferencias para actualizar la visualización del explorador de la interfaz de usuario y la versión del explorador de DOM que JavaScript usa.

Muchas bibliotecas de JavaScript de terceros están disponibles para representar elementos en una página y estas bibliotecas pueden actualizar el DOM. Si el código de JavaScript modifica elementos de DOM, es posible que la copia de Blazor del DOM ya no coincida con el estado actual. Esta situación puede provocar un comportamiento inesperado y, posiblemente, introducir riesgos de seguridad. Es importante no realizar cambios que puedan dañar la vista Blazor del DOM.

La manera más sencilla de controlar esta situación es crear un elemento de marcador de posición en el componente de Blazor, normalmente un elemento <div @ref="placeHolder"></div> vacío. El código de Blazor interpreta este código como un espacio en blanco y el árbol de representación de Blazor no intenta realizar un seguimiento de su contenido. Puede agregar libremente los elementos de código de JavaScript a este <div> y Blazor no intentará cambiarlo.

El código de la aplicación de Blazor define un campo de tipo ElementReference para contener la referencia al elemento <div>. El atributo @ref del elemento <div> establece el valor del campo. A continuación, el objeto ElementReference pasa a una función de JavaScript, que puede usar la referencia para agregar contenido al elemento <div>.

Llamada a código de .NET desde JavaScript

El código de JavaScript puede ejecutar un método de .NET que el código de Blazor define mediante la clase de utilidad DotNet, parte de la biblioteca de interoperabilidad de JS. La clase DotNet expone las funciones auxiliares invokeMethod e invokeMethodAsync. Use invokeMethod para ejecutar un método y esperar el resultado, o use invokeMethodAsync para llamar al método de manera asincrónica. El método invokeMethodAsync devuelve un objeto Promise de JavaScript.

Sugerencia

Para mantener la capacidad de respuesta en las aplicaciones, defina el método de .NET como async y llámelo mediante invokeMethodAsync desde JavaScript.

Debe etiquetar el método de .NET al que se llama con JSInvokableAttribute. El método debe ser public y todos los parámetros debe ser serializables con JSON. Además, para un método asincrónico, el tipo de valor devuelto debe ser void, Task o un objeto Task<T> genérico, donde T es un tipo serializable con JSON.

Para llamar a un método static, debe proporcionar el nombre del ensamblado de .NET que contiene la clase, un identificador para el método y los parámetros que el método acepta como argumentos para las funciones invokeMethod o invokeMethodAsync. De manera predeterminada, el identificador del método es el mismo que el nombre del método, pero se puede especificar un valor diferente mediante el atributo JSInvokable.

Llamada a un método de instancia de .NET desde JavaScript

Para ejecutar un método de instancia, JavaScript requiere una referencia de objeto que apunte a la instancia. La interoperabilidad de JS proporciona el tipo DotNetObjectReference genérico que se puede usar para crear una referencia de objeto en el código de .NET. El código debe hacer que esta referencia de objeto esté disponible para JavaScript.

A continuación, el código de JavaScript puede llamar a invokeMethodAsync con el nombre del método de .NET y los parámetros que el método requiere. Para evitar pérdidas de memoria, el código de .NET debe eliminar la referencia de objeto cuando ya no sea necesaria.

Comprobación de conocimientos

1.

¿Dónde debe agregar la etiqueta script para hacer referencia a un archivo JavaScript que incluya en Blazor?

2.

¿Qué método de C# debe usar para ejecutar una función de JavaScript que devuelva void?