Исходные коды программ и игр

Программирование - работа и хобби

Blazor вызов функций JavaScript

Язык программирования C#

Для чего JavaScript в Blazor

Взаимодействие Blazor и JavaScriptBlazor ещё очень молодой, но уже обладает значительными возможностями создания пользовательских интерфейсов на языке C#. Разработчики очень быстро развивают это перспективное направление для создания интерактивных веб приложений. Но Blazor не ограничен только серверным кодом и поддерживает совместную работу со скриптами JavaScript. Надо отдать должное языку JavaScript, он как мостик соединяет все виды серверных языков с HTML элементами страниц в браузере. В большинстве случаев не обязательны глубокие познания JavaScript, но умение на нём писать небольшие скрипты очень желательно.

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

Пока Blazor приложениям недоступен контроль над деревом DOM (объектная модель документа) страницы в браузере и поэтому без кодирования на JavaScript не обойтись. Интерактивностью своих приложений Blazor также обязан JavaScript.

Взаимодействие JavaScript и Blazor

Для вызова функций JavaScript используется абстракция посредством интерфейса IJSRuntime. IJSRuntime необходимо внедрить в компонент Blazor конструкцией из директивы с параметрами @inject IJSRuntime JSRuntime. Интерфейс IJSRuntime имеет две разновидности методов: InvokeAsync(string identifier, ...) и InvokeVoidAsync(string identifier, ...). Один из параметров этих методов должен указывать на идентификатор функции JavaScript.

Идентификатором является имя функции относительно глобальной области (window) обрамляемое кавычками. Например: существует JavaScript функция window.name_function, её идентификатором будет "name_function", если функция находится в каком-либо пространстве имён, то в идентификаторе должно присутствовать и пространство имён, например window.namespace.name_function, идентификатор "namespace.name_function".

Режимы прорисовки страниц

Приложения Blazor имеют несколько режимов обработки компонентов: ServerPrerendered, Server, Static. Интерактивность веб страниц поддерживается только в первых двух режимах, третий режим преобразует компоненты в статические HTML страницы. Настройка режимов отображения компонентов осуществляется в файле приложения Blazor Server _Host.cshtml.

Структура кода файла _Host.cshtml:
@page "/"
...
<!DOCTYPE html>
<html lang="en">
<head>
  ...
</head>
<body>
    <!-- Установлен режим предварительной прорисовки страницы на сервере -->
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
        
        <!-- Возможные режимы отображения компонентов -->
        <!-- <component type="typeof(App)" render-mode="Server" /> -->
        <!-- <component type="typeof(App)" render-mode="Static" /> -->
    </app>

   ...
</body>
</html>

Интерактивные режимы

Наиболее "полноценный" режим с серверной предварительной прорисовкой компонентов "ServerPrerendered". В этом случае компоненты Blazor преобразуются в HTML разметку со способностью интерактивной работы приложения. Данный режим для приложений Blazor Server установлен по умолчанию. При просмотре исходного текста страницы в браузере будут видны элементы гипертекстовой разметки определённой в компонентах и специальный код для загрузки приложения.

При установленном режиме обработки кода со значением Server метка приложения присутствует в исходном тексте страницы, а HTML код компонентов не выводится. Интерактивность приложения при этом сохраняется.

Для приложений с режимом обработки ServerPrerendered и Server вызовы функций JavaScript должны осуществляться после завершения формирования модели DOM и установления соединения с браузером. Определять вызовы активаций JavaScript функциональностей рекомендуется в методе жизненного цикла компонента OnAfterRenderAsync(bool firstRender), который вызывается после окончания каждой прорисовки компонента. Параметр firstRender после первого вызова устанавливается в false и даёт возможность создания блока кода который исполняется только один раз, при инициализации приложения Blazor.

Данный метод компонента вызывается после завершения отрисовки:
@code{
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        // Параметр гарантирует, что код в блоке будет вызываться однократно,
        // только при инициализации приложения.
        if (firstRender == true)
        {
            await InvokeVoidAsync("name_function_javascript");

            // или с возвратом:
            // var value = await JSRuntime.InvokeAsync("name_function_javascript");
        }
}

Исходник приложения Blazor + JavaScript

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

QRCode.js - создание QR-кода

QRCodejs - кросс-браузерный генератор QR-кода. В нашем приложении на основе этой библиотеки создаётся веб страница с возможностью создания QR-кода и загрузки его в виде файла изображения. Подробнее о библиотеке на QRCodejs.

Подключение библиотеки QR-кодов происходит в файл _Host.cshtml тегом с параметрами
<script type="text/javascript" src="~/qrcodejs/qrcode.js"></script>

<!-- Подключение скрипта взаимодействия QRCode.js с Blazor  -->
<script type="text/javascript" src="~/qrcodejs/blazor-qrcodejs.js"></script>

Для работы приложения Blazor с QRCode.js создадим собственный скриптовый код оборачивающий функции библиотеки в удобные оболочки. При использовании приложением нескольких JavaScript библиотек желательно коды для их управления помещать в отдельные пространства имён. В листинге кода JavaScript ниже создаются функции активации библиотеки, создания QR-кода и загрузки картинки с изображением QR-кода.

Листинг собственного файла blazor-qrcodejs.js для управления библиотекой создания QR-кода:
var qrcode = {
    obj: null,
    start: function (w, h) {
        this.obj = new QRCode(document.getElementById("qrcode"), {
            width: w,
            height: h
        });
    },
    makeCode: function (_text) {
        if (this.obj != null) this.obj.makeCode(_text);
    },
    downloadQRImg: function () {
        let a = document.createElement("a");
        let e = document.getElementById("qrcode");
        let src = e.getElementsByTagName("img")[0].getAttribute("src");
        a.href = src;
        a.download = "QRCode.png";
        a.click();
    }
}

Компонент создания QR-кода стандартно включает HTML разметку и программный код на C#. События HTML элементов связываются с методами серверного кода. Все методы работают асинхронно, что благоприятно сказывается на комфортность пользовательского общения с интерфейсом приложения.

Один из многих лайфхаков Blazor Server содержится в коде элемента textarea - это контроль ограничение длины вводимого текста серверной переменной maxlength="@limit" . В "обычном" веб приложении приходится повторять такие проверки дважды: для удобства - на клиентской стороне на JavaScript, и для безопасности на серверной.

Листинг кода компонента создания QR-кода:

@inject IJSRuntime JSRuntime
<div class="row">
    <div class="col">
        <textarea id="text" @bind-value="@text" @bind-value:event="oninput" 
                        maxlength="@limit" rows="3" placeholder="Введите текст..."></textarea>
        <div id="qrcode" class="my-3"></div>
        <button class="btn btn-outline-secondary" @onclick="CreateQRCode">Создать QR-код</button>
        <button class="btn btn-outline-secondary" @onclick="ClearQRCode">Сброс</button>
        <button class="btn btn-outline-secondary" @onclick="DownloadQR">Загрузить</button>
    </div>
</div>
@code {
    private int limit = 200;
    private string text = "";
	
    // Создание картинки с QR-кодом по данным текстового аргумента.
    private async Task CreateQRCode() => await MakeCode(this.text);
    // Метод сброса процесса к началу
    private async Task ClearQRCode() => await MakeCode(this.text = "");
    // Общий метод
    private async Task MakeCode(string _text) => await JSRuntime.InvokeVoidAsync("qrcode.makeCode", _text);
    // Загрузка картинки с QR-кодом по желанию пользователя.
    private async Task DownloadQR() => await JSRuntime.InvokeVoidAsync("qrcode.downloadQRImg");

    // После того как все элементы DOM веб страницы загружены.
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            // Активация интерфейса для генерации QR-кодов.
            await JSRuntime.InvokeVoidAsync("qrcode.start", 320, 320);
            await CreateQRCode();
        }
    }
}

Chart.js - красочные диаграммы JavaScript

Chart.js - простые в применении анимированные диаграммы. Можно создавать сложные наборы данных с указанием даты и времени с потрясающими переходами при изменении данных. Документация и примеры на сайте Chart.js.

Библиотека диаграмм подключается аналогично вышеописанной QRCode.js. В первую очередь подключается скрипт-файл Chart.js, затем подключаем файл функций взаимодействия с кодом компонента blazor-chart.js. Инициализация функций JavaScript происходит после окончания прорисовки компонента. У диаграмм динамически можно изменять значения и вид.

Листинг запуска библиотеки диаграмм:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
	if (firstRender)
	{
		// Активируем график
		await JSRuntime.InvokeVoidAsync("chartJS.start");
		await UpdateValue();
		await ChangeType();
	}
}

JQVmap - векторная карта jQuery

JQVmap - плагин на jQuery для приложений и сайтов, которым требуются интерактивные карты. Библиотека рисует карты стран и мира. Выделять страны цветом можно программно или кликая по секторам регионов.

Функционал подключения векторной карты Мира в своём составе дополнительно имеет базу данных. Роль базы данных выполняет класс DataRegions. Данные построены на модели содержащей название страны, двухзначный код ISO и цвет выделения.

Листинг кода модели регионов:
// Модель данных регионов.
public class RegionItem
{
	public string Name { get; set; }
	public string ISO { get; set; }
	public string Color { get; set; }
}

Файл исходника

Приложение Blazor с подключением JavaScript библиотек создано в среде программирования MS Visual Studio 2019. Для работы приложения необходимо установить .NET Core 3.1. Архив исходника прикреплен ниже.

Просмотр демо 🔎

Файл: BlazorJavaScript-vs16.zip
Размер: 1577 Кбайт
Загрузки: 14