Блазор и JavaScript

Хотя Blazor хорошо подходит для разработки веб-приложений, в некоторых сценариях вам потребуется использовать некоторые возможности браузера, к которым у Blazor все еще нет доступа, или в некоторых случаях вы хотите воспользоваться преимуществами функциональных возможностей некоторых библиотек JavaScript. По этим и другим причинам платформы Blazor позволяют вызывать функции JavaScript из методов .Net.

Blazor предлагает нам абстракцию под названием IJSRuntime. С его помощью мы можем вызывать метод JavaScript, а также отправлять аргументы.

Сначала нам нужно структурировать код JavaScript и расположить его в нужном месте, чтобы он был доступен, когда мы хотим его вызвать. Согласно документации Blazor, в зависимости от того, какой тип проекта Blazor вы используете, вы должны поместить код JavaScript в одно из следующих мест.

Inside wwwroot/index.html (Blazor client-side) or Pages/_Host.cshtml (Blazor server-side)

Вместо того, чтобы напрямую вставлять код JavaScript, мы добавим его в файл, а затем включим, как и любой другой файл JavaScript. Наша функция JS получит текст и назначит его элементу.

window.Tools = { SetText: function (newText) { console.log(newText); document.getElementById("title").innerHTML = newText; return newText; } };

Мы включим функцию Javascript

wwwroot/index.html (на стороне клиента Blazor):

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>Blazor Sample</title> <base href="/" /> <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" /> <link href="css/site.css" rel="stylesheet" /> </head> <body> <app>Loading...</app> <script src="_framework/blazor.webassembly.js"></script> <script src="myJsInteropFunctions.js" ></script> </body> </html>

Pages/_Host.cshtml (Blazor на стороне сервера):

@page "/" @namespace blazorsample.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers <!DOCTYPE html> <html> <head> : : </head> <body> <app>@(await Html.RenderComponentAsync<App>())</app> <script src="_framework/blazor.server.js"></script> <script src="myJsInteropFunctions.js" ></script> </body> </html>
NOTE: Don't place a <script> tag in a component file because the <script> tag can't be updated dynamically.

Чтобы вызвать функцию JavaScript из .Net, мы будем использовать абстракцию IJRuntime. Blazor предлагает несколько способов использования IJRuntime:

@page "/" @inject IJSRuntime JSRuntime <h1 id="title">Hello, world!</h1> Welcome to your new app. @code{ }
using System.Threading.Tasks; namespace BlazorJSInterop.Shared.Services { public class JSSerivce { private readonly IJSRuntime _jsRuntime; public JSSerivce(IJSRuntime jsRuntime) { _jsRuntime = jsRuntime; } public Task<string> SetText(string text) { return _jsRuntime.InvokeAsync<string>( "SetText", text); } } }

Для создания динамического контента с помощью BuilderRenderTree используйте атрибут [Inject].

@page "/counter" <h1>Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="@IncrementCount">Click me</button> @code { [Inject] IJSRuntime JSRuntime { get; set; } int currentCount = 0; void IncrementCount() { currentCount++; } }

Чтобы начать использовать IJSRuntime, мы будем вызывать нашу функцию JavaScript при загрузке приложения. Имейте в виду, что IJSRuntime необходимо вызывать после рендеринга компонента. Например, в этом случае мы будем вызывать функцию JS в жизненном цикле OnAfterRenderd компонента.

@page "/" @inject IJSRuntime JSRuntime <h1 id="title">Hello, world!</h1> Welcome to your new app. @code{ protected override void OnAfterRender() { JSRuntime.InvokeAsync<object>( "SetText", "OnAfterRender was Triggered"); } }

Как только компонент завершит рендеринг, он установит внутренний HTML-код элемента на «OnAfterRender was Triggered», мы также можем сослаться на элемент и отправить его в функцию JS. Мы добавляем параметр nee в функцию JavaScript

window.Tools = { SetText: function (newText, elemntRef) { console.log(newText); elemntRef.innerHTML = newText; return newText; } };
<h1 @ref="title">Hello, world!</h1> @code{ ElementRef title; protected override void OnAfterRender() { JSRuntime.InvokeAsync<object>( "SetText", "OnAfterRender was Triggered", title); } }
NOTE: For server-side apps: *	Multiple user requests are processed by the server-side app. Don't call JSRuntime.Current in a component to invoke JavaScript functions. *	Inject the IJSRuntime abstraction and use the injected object to issue JavaScript interop calls. *	While a Blazor app is prerendering, calling into JavaScript isn't possible because a connection with the browser hasn't been established. For more information, see the Detect when a Blazor app is prerendering section.

Blazor также предлагает возможность вызывать метод C# .Net из функции JavaScript. Чтобы вызвать статический метод .Net из JavaScript, используйте функции DotNet.invokeMethod или DotNet.invokeMethodAsync. Чтобы сначала проверить это, мы добавим функцию JavaScript, эта функция будет вызывать наш метод .Net.

window.Tools = { SetText: function (newText, elemntRef) { console.log(newText); elemntRef.innerHTML = newText; return newText; }, csharpMethod: function (){ DotNet.invokeMethodAsync('BlazorJSInterop', 'ReturnArrayAsync') .then(data => { data.push("Blazor"); console.log(data); }); } };

Теперь мы создадим метод .Net, который будет вызываться

@page "/counter" <h1>Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="@IncrementCount">Click me</button> <button class="btn btn-primary" @onclick="Tools.csharpMethod()">C# Mehtod</button> @code { [Inject] IJSRuntime JSRuntime { get; set; } int currentCount = 0; void IncrementCount() { currentCount++; } [JSInvokable] public static Task<string[]> ReturnArrayAsync() { return Task.FromResult(new string[] { "Nativo", "Plus", "MedConex" }); } }

Новая кнопка вызовет функцию JavaScript, которая вызовет метод .Net. Для простоты мы получим массив строк из метода .Net и заставим JavaScript добавить новую строку в массив, а затем зарегистрируем массив в консоли.

Вы можете использовать эти знания, чтобы обернуть любую функцию JavaScript, которая может понадобиться, вы даже можете создать свои собственные службы .Net, использующие преимущества библиотеки JavaScript. Если вы хотите протестировать Blazor JSInterop, вы можете отправиться в Репозиторий на github.

Первоначально опубликовано на https://www.nativoplus.studio 16 июля 2019 г.