Blazor - Isolamento de JavaScript (.NET 5)

Hoje veremos como usar o recurso do isolamento JavaScript do Blazor no ambiente do .NET 5.

Se você esta chegando agora e não sabe o que é o Blazor leia o artigo ASP .NET Core - Iniciando com o Blazor - Macoratti; se você já conhece e quer saber mais pode fazer o curso de Blazor Essencial.  

Blazor - Isolamento de JavaScript

Um aplicativo Blazor pode invocar funções JavaScript a partir de métodos .net. Esse cenário é  chamado de interoperabilidade JavaScript.

O isolamento JavaScript disponível no Blazor a partir do .NET 5.0 permite carregar o código JavaScript para um componente específico sem precisar definir o arquivo JavaScript no escopo global Window.

Um dos objetivos do isolamento de JS é fazer componentes reutilizáveis que não sejam afetados pelo escopo global. Na versão anterior do Blazor, você precisava expor a função JavaScript no escopo global (Window) e adicionar o elemento <script> manualmente.  Agora você não precisa mais salvar seu objeto JavaScript no namespace global Window, basta exportar sua função ou objeto Javascript. E também não precisa importar arquivos JavaScript manualmente em sua marcação HTML.

O isolamento JS esta baseado em módulos ES padrão que podem ser carregados sob demanda usando let meumodule = import ("path") e as funções que eles expõem são acessíveis apenas a partir do objeto retornado. Dessa forma agora você pode criar bibliotecas facilmente reutilizáveis.

Na plataforma .NET você pode usar módulos ES através da interface  IJSRuntime e da classe JSObjectReference, onde :

  1.  IJSRuntime.InvokeAsync permite chamar de forma assíncrona a função JavaScript especificada;
  2.  JSObjectReference permite manter uma referência ao módulo ES carregado;

Exemplo de código usado para carregar o módulo ES e manter uma referência a ele.(Precisamos usar .AsTask() para converter o ValueTask para Task visto que ele pode ser awaited muitas vezes) :

private Task<JSObjectReference> _module;
private Task<JSObjectReference> Module => _module ??= JSRuntime.InvokeAsync<JSObjectReference>("import", "./js/demo.js").AsTask();

Vejamos a seguir um exemplo prático usando este recurso.

Recursos usados:

Criando o projeto no VS Community 2019

Abra o VS 2019 Community (versão mínima 16.6) e selecione a opção Create a New Project;

A seguir selecione a opção Blazor app e clique em next;

Informe o nome do projeto :  Blazor_IsolaJS1 a localização e clique em Create;

Escolha .NET 5.0 e selecione a opção - Blazor WebAssembly App e clique no botão Create para criar o projeto.

Para criar o projeto na linha de comando usando o NET CLI digite : dotnet new blazorwasm -o Blazor_IsolaJS1

A seguir vamos limpar o projeto criado usando o template excluindo os arquivos destacados e mostrados na figura abaixo:

A seguir altere o código do componente Index.razor.

Criando a função Javascript na pasta wwwroot/js

Na pasta wwwroot vamos criar a pasta js e nesta pasta vamos criar o arquivo JavaScript chamado saudacoesJS.js com o seguinte código :

export function saudacoes(nome) {
    alert(`Feliz ano novo, ${nome}!`);
}

Observe que estamos usando a sintaxe de modulo Javascript para exportar a função saudacoes e que não precisamos mais atribuir o nosso arquivo javascript ao objeto global Window assim nosso código JavaScript esta complemente isolado.

Agora veremos como chamar esta função Javascript a partir do Blazor.

Chamando o código JavaScript a partir do Blazor

Vamos agora alterar o código do componente Index.razor conforme abaixo:

@page "/"

@inject IJSRuntime jsRuntime

<h3>Usando isolamento JavaScript com JSObjectReference</h3>

Qual o seu nome : <input @bind="nome" />

<button @onclick="Submit">Ver Saudação</button>

@code {

     private string nome;
     private IJSObjectReference module;

     protected override async void OnInitialized()
     {
         module = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "./js/saudacoesJS.js");
     }

     async Task Submit()
     {
         await module.InvokeVoidAsync("saudacoes", nome);
     }
}

Vamos entender o código:

Estamos injetando o serviço IJSRuntime que representa uma instância do runtime JavaScript para qual despachamos as chamadas criando a instância do serviço com o nome jsRuntime

A seguir estamos usando um input para solicitar o nome do usuário e criando um button com o evento onclick que vai chamar o método Submit.

No código do componente estamos definindo uma instância de IJSObjectReference que representa uma referência ao objeto Javascript.

No evento OnInitialized() do componente estamos carregando o módulo Javascript - saudacoesJS.js - da pasta www/js

No método Submit, acionado quando o usuário clicar no botão de comando, estamos invocando a função javascript saudacoes e passando o nome que o usuário informou.

Ao executar o projeto teremos o resultado esperado:

De forma resumida na inicialização do componente, atribuímos a instância IJSObjectReference e usando o método jsRuntime.InvokeAsynccarregamos” o módulo JavaScript na variável module.

Para fazer isso, usamos o serviço IJSRuntime injetado, que faz parte do Blazor.

O argumento “import” é usado especificamente para importar um módulo JavaScript. O caminho para o módulo (relativamente ao diretório wwwroot/js) é especificado dentro do segundo argumento.

A seguir chamamos a função Javascript - saudacoes - passando o parâmetro nome.

Pegue o projeto aqui:  Blazor_IsolaJS1.zip  (sem as referências)

"Quem, pois, tiver bens do mundo, e, vendo o seu irmão necessitado, lhe cerrar as suas entranhas, como estará nele o amor de Deus? Meus filhinhos, não amemos de palavra, nem de língua, mas por obra e em verdade."
1 João 3:17,18
 


Referências:


José Carlos Macoratti