С помощью класса NavigationManager в коде C# компонентов Blazor можно управлять навигацией. Это абстрактный класс, и в общем случае фреймворк Blazor сам создает сервис этого типа, который мы можем получить в копмоненте с помощью встроенного механизма внедрения зависимостей:
@inject NavigationManager Navigation
Прежде всего NavigationManager предоставляет ряд свойств, которые позволяют получить некоторую информацию о состоянии навигации:
Uri: текущий адрес
BaseUri: базовый адрес приложения. Обычно устанавливается с помощью элемента <base>
на html-странице
HistoryEntryState: состояние истории навигации
Рассмотрим простейший пример. Пусть у нас есть два компонента - Home и About.
Например, получение текущего адреса в компоненте:
@page "/about" @inject NavigationManager Navigation <h3>@Navigation.Uri</h3>
дополнительно с помощью метода ToBaseRelativePath() можно получить относительный путь, а с помощью метода ToAbsoluteUri() - абсолютный адрес. Например:
@page "/about" @inject NavigationManager Navigation <h2>About Page</h2> <h3>Absolute: @Navigation.Uri</h3> <h3>Relative: @Navigation.ToBaseRelativePath(Navigation.Uri)</h3>
Для программной навигации у класса NavigationManager применяется метод NavigateTo(). Этот метод имеет три версии
public void NavigateTo (string uri, bool forceLoad); public void NavigateTo (string uri, bool forceLoad = false, bool replace = false); public void NavigateTo (string uri, Microsoft.AspNetCore.Components.NavigationOptions options);
Все три версии в качестве первого параметра принимают адрес перехода. Это может быть как абсолютный адрес, так и относительный путь.
Булевый параметр forceLoad
при значении true
указывает, что надо вместо клиентской маршрутизации использовать маршрутизацию сервера. То есть переход
обрабатывается НЕ клиентской системой маршрутизации, а сервером.
Булевый параметр replace
при значении true
заменяет текущую запись в истрии браузера. Если же он равен false
в историю браузера добавляется
новая запись.
Последняя версия метода принимает объект NavigationOptions
, который позволяет установить те же самые возможности, что и параметры forceLoad
и replace
.
Например, выполним программый переъод с одного компонента на другой. В компоненте About определим следующий код:
@page "/about" <h2>About Page</h2>
Тут ничего примечательного кроме того, что компонент обрабатывает запросы по пути "/about". И в компоненте Home определим переход к компоненту About:
@page "/" @using Microsoft.AspNetCore.Components.Web @rendermode RenderMode.InteractiveServer @inject NavigationManager Navigation <h2>Home Page</h2> <button @onclick="GoToAbout">To About Page</button> @code{ void GoToAbout() { Navigation.NavigateTo("about"); } }
Здесь по нажатию на кнопку вызывается метод GoToAbout()
выполняется навигация по пути "/about", то есть к компоненту About.
С помощью события LocationChanged у NavigationManager мы можем отслеживать переходы между компонентами с помощью NavigationManager. В качестве аргумента событие
LocationChanged
принимает объект LocationChangedEventArgs, через который можно получить информацию о смене расположения. В частности, через
свойство Location можно получить новый адрес, на который выполняется переход.
Рассмотрим на примере. Изменим код компонента Home следующим образом:
@page "/" @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @rendermode RenderMode.InteractiveServer @inject NavigationManager Navigation @implements IDisposable <h2>Home Page</h2> <p><a href="/about">About</a></p> <button @onclick="GoToAbout">To About Page</button> @code{ void GoToAbout() { Navigation.NavigateTo("/about"); } protected override void OnInitialized() { Navigation.LocationChanged += HandleLocationChanged; } private void HandleLocationChanged(object? sender, LocationChangedEventArgs e) { Console.WriteLine($"URL of new location: {e.Location}"); } public void Dispose() { Navigation.LocationChanged -= HandleLocationChanged; } }
В компоненте Home определена ссылка на компонент About, а также кнопка, по нажатию на которую также происходит переход к компоненту About.
Чтобы подписаться на событие в методе OnInitialized()
, который срабатывает при инициализации компонента, устанавливаем для события обработчик:
protected override void OnInitialized() { Navigation.LocationChanged += HandleLocationChanged; }
В обработчике HandleLocationChanged просто выводим на консоль новый адрес, на который выполняется переход:
private void HandleLocationChanged(object? sender, LocationChangedEventArgs e) { Console.WriteLine($"URL of new location: {e.Location}"); }
Поскольку мы имеем дело с событиями, то нам надо отписаться от них в методе Dispose
@implements IDisposable // реализуем интерфейс IDisposable //............... public void Dispose() { Navigation.LocationChanged -= HandleLocationChanged; }
И вне зависимости от того, как мы будем переходить к компоненту About - по нажатию на ссылку или программно по нажатию на кнопку, в обоих случаях сработает обработчик HandleLocationChanged, и на консоль будет выведена строка с новым адресом