Использование маршрутизации Wasaby
В этой статье даны примеры создания страниц и настройки маршрутов.
Настройка маршрутизации для конкретных приложений СБИС, например online.sbis.ru, может иметь свои особенности. Поэтому перед началом работы рекомендуется обратить внимание на связанные с темой статьи:
- Маршрутизация
- SEO controls
- Создание веб-страниц в приложении online.sbis.ru
- Правила составления «хороших» URL в приложении online.sbis.ru
Создание новой страницы
Страницей считается контрол с названием Index
, который находится в корне интерфейсного модуля.
- Создадим новый интерфейсный модуль (например,
Travel
). - Создадим в этом модуле контрол
Index
с шаблоном приложения.
// Travel/Index.ts
import * as Control from 'Core/Control';
import * as template from 'wml!Travel/Index';
export default class TravelPage extends Control {
protected _template: Function = template;
}
<!-- Travel/Index.wml -->
<SbisEnvUI.Bootstrap>
<div>
<h1>Страница Travel!</h1>
</div>
</SbisEnvUI.Bootstrap>
Эта страница становится доступна по адресам, начинающимся с /Travel/
. Для определения, какое приложение должно быть загружено для заданного URL-адреса, используется механизм сопоставления маршрутов.
Создание новой страницы в приложении online.sbis.ru
На online.sbis.ru используется система маршрутизации, которая основана на сведениях из настоящей статьи. В ней используется собственный подход к созданию и конфигурации страниц. Подробнее об этом читайте в статье.
Сопоставление маршрутов
При переходе по URL-адресу определяется соответствующее ему приложение:
- Изменяется префикс URL-адреса согласно таблице замен
router.json
. Подробнее об этом файле будет сказано далее. - Из получившегося адреса извлекается подстрока между первыми двумя слэшами. Она используется в качестве названия интерфейсного модуля.
- Данный URL-адрес соответствует приложению в контроле
Index
полученного интерфейсного модуля.
Таблица замен собирается из файлов router.json
, которые могут содержаться в любом интерфейсном модуле. Она содержит информацию о том, как необходимо изменить URL-адрес перед поиском соответствующего ему приложения.
Файл router.json
должен находиться в корне интерфейсного модуля и иметь следующий формат:
// router.json
{
"префикс url": "замена префикса",
"префикс url 2": "замена 2",
...
}
На первом шаге маршрутизации выполняется обход этого списка. В нем ищется самый длинный префикс, который совпадает с началом текущего URL-адреса. После завершения поиска, если такой префикс был найден, выполняется его замена в URL-адресе на соответствующую строку.
Это можно использовать например для того, чтобы сделать приложения доступными по адресам, отличным от названий их интерфейсного модуля. Например:
// router.json
{
"Books": "BookShop",
"Books/Bestselling": "ExpensiveShop/Books/Best",
"Tickets": "TicketShop"
}
В этом примере при переходе по адресу /Books/
будет найден самый длинный подходящий префикс Books
и совершен переход по адресу /BookShop/
, то есть будет загружено приложение BookShop/Index
.
При переходе по адресу /Books/Bestselling/2019
наиболее подходящий префикс — Books/Bestselling
, поэтому будет совершен переход по адресу /ExpensiveShop/Books/Best/2019
, и загружено приложение ExpensiveShop/Index
.
Для адреса /Buy/Tickets
в таблице префикса нет, поэтому он останется без изменений, и будет загружено приложение Buy/Index
.
Таблица замен влияет только на сопоставление адресов определенным приложениям. Пользователь продолжает видеть в адресной строке браузера исходный URL-адрес до замены. При этом сопоставление маршрута и все контролы роутинга будут работать с измененным адресом.
В router.json
также может задаваться особая "корневая" замена с помощью префикса "/". Эта замена применяется только при переходе на корневой URL-адрес с возможностью наличия в адресе query-параметров, то есть параметров вида name=value
.
Это можно применить, чтобы контрол Travel/Index
из примера был доступен по корневому маршруту:
// router.json
{
"/": "Travel"
}
При такой замене, по адресам /
, /?promo=true
и т.д. будет открываться приложение Travel/Index
. При этом, по адресу /abc
будет доступно уже приложение abc/Index
.
Добавление адресов в файл router.json
должно быть согласовано с ответственным за приложение. Для online.sbis.ru
такое согласование должно быть с Новиковым Д.В.. Также для online.sbis.ru
такая замена должна быть описана в конфигурации онлайн-роутинга.
Во время сборки файлы router.json
из всех интерфейсных модулей объединяются в один, который представляет собой единую таблицу замен.
Вложенные маршруты
Так как за приложение отвечает часть адреса между первыми двумя слэшами URL-адреса, остальной адрес может свободно использоваться внутри этого приложения. Для изменения и добавления параметров URL-адреса используются контролы роутинга.
- Добавим на страницу список стран, при клике на которые их названия будут записываться в URL-адрес, с помощью контрола Router/router:Reference.
// Travel/Index.ts
...
export default class TravelPage extends Control {
protected _template: TemplateFunction = template;
// Добавляем список стран
private _countries = {
'russia': {
name: 'Россия',
cities: ['Москва', 'Санкт-Петербург', 'Новосибирск']
},
'italy': {
name: 'Италия',
cities: ['Рим', 'Милан', 'Неаполь']
},
'france': {
name: 'Франция',
cities: ['Париж', 'Марсель', 'Лион']
}
};
}
<!-- Travel/Index.wml -->
...
<h1>Страница Travel!</h1>
<div class="countries">
<span class="countries__title">Выберите страну отправления:</span>
<!-- Выводим ссылки на все страны списком -->
<ul class="countries__list">
<ws:for data="urlName, country in _countries">
<li>
<Router.router:Reference
state="country/:countryName"
countryName="{{ urlName }}">
<a href="{{ content.href }}">{{ country.name }}</a>
</Router.router:Reference>
</li>
</ws:for>
</ul>
</div>
...
- При клике на ссылки, в адресной строке браузера появится и будет изменяться параметр
country/<название страны>
. Для чтения параметров из URL-адреса используется контрол Router/router:Route. Используем его для отображения списка городов выбранной страны.
<!-- Travel/Index.wml -->
...
<div class="countries">...</div>
<Router.router:Route mask="country/:cName">
<div class="cities">
<!-- Отображаем города только если страна выбрана, и она есть в списке -->
<ws:if data="{{ content.cName && _countries[content.cName] }}">
<span class="cities__title">Города страны {{ _countries[content.cName].name }}:</span>
<ul class="cities__list">
<ws:for data="city in _countries[content.cName].cities">
<li>{{ city }}</li>
</ws:for>
</ul>
</ws:if>
</div>
</Router.router:Route>
...
Таким образом, выбор страны из списка стран приводит к изменению URL-адреса. При изменении адреса обновляется контрол Route
, его шаблон перестраивается, на экране отображается новый список городов.
Так как контрол Route
реагирует на любое изменение адреса, появляется поддержка кнопок вперед/назад браузера. Если кликнуть на ссылку "Россия", затем на ссылку "Франция", то при переходе по истории браузера, Route
также будет обновляться и перерисовывать список городов.
Route
работает на Сервисе представлений, что позволяет при переходе по адресу /Travel/country/italy
сразу получить с сервера построенную верстку, включающую в себя список городов Италии.
Более подробное описание работы с контролами Route
и Reference
, а также инструкцию по запуску демо-примеров, можно найти в здесь.
Переход между приложениями
Переход с приложения Index
одного интерфейсного модуля на Index
другого может происходить без перезагрузки страницы. Такой переход происходит, если Router/router:Reference
переадресует пользователя по такому адресу, для которого алгоритм сопоставления маршрутов вернет приложение, отличное от текущего.
- Создадим новый интерфейсный модуль
Purchases
, и добавим в него приложениеIndex
.
<!-- Purchases/Index.wml -->
<SbisEnvUI.Bootstrap>
<div>
<h1>Страница Purchases</h1>
</div>
</SbisEnvUI.Bootstrap>
Purchases/Index.ts
должен экспортировать контрол, с установленным шаблоном Purchases/Index.wml
. 2. На странице Travel/Index добавим ссылку, перенаправляющую на новую страницу.
<!-- Travel/Index.wml -->
...
<Router.router:Reference
state="/Purchases">
<a href="{{ content.href }}">Перейти к Purchases</a>
</Router.router:Reference>
...
При нажатии на эту ссылку, будет совершен переход к приложению Purchases/Index
, оно будет загружено вместо текущего приложения Travel
.
Если контрол Index
из интерфейсного модуля, на который ссылается путь Reference
, загрузить не удается, предполагается что этот адрес как-то обрабатывается на сервисе представлений, поэтому производится стандартный переход с перезагрузкой страницы.
Для работы переходов между приложениями на онлайне (в том числе и через аккордеон), они должны быть описаны в конфигурации онлайн-роутинга.