Blazor ещё очень молодой, но уже обладает значительными возможностями создания пользовательских интерфейсов на языке C#. Разработчики очень быстро развивают это перспективное направление для создания интерактивных веб приложений. Но Blazor не ограничен только серверным кодом и поддерживает совместную работу со скриптами JavaScript. Надо отдать должное языку JavaScript, он как мостик соединяет все виды серверных языков с HTML элементами страниц в браузере. В большинстве случаев не обязательны глубокие познания JavaScript, но умение на нём писать небольшие скрипты очень желательно.
Использование скриптов в приложениях Blazor необходимо для подключения готовых библиотек, обогащения функциональностью веб страниц и расширения возможностей веб приложений. Но даже в этом случае основная логика пишется на C# и уже готовые данные отправляются функциям JavaScript.
Пока Blazor приложениям недоступен контроль над деревом DOM (объектная модель документа) страницы в браузере и поэтому без кодирования на JavaScript не обойтись. Интерактивностью своих приложений Blazor также обязан JavaScript.
Для вызова функций 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 библиотек. В приложении будут создаваться 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; }
}